Triangle Peg Solitaire(孔明棋)
package com.game.board;import java.util.List;
import java.util.ArrayList;public class GameBoard {// board consists of pegs and holes in a 5 x 5, but only uses triangular pyramidboolean[][] pins = new boolean[5][5];public GameBoard(int row, int col) {for (int i = 0; i < 5; ++i)for (int j = 0; j <= i; ++j)pins[i][j] = true;pins[row][col] = false;}public GameBoard(int board) {for (int i = 4; i >= 0; --i)for (int j = i; j >= 0; --j) {if ((board & 1 ) == 1) pins[i][j] = true;elsepins[i][j] = false;board /= 2;}}// copy constructorpublic GameBoard(GameBoard that) {for (int i = 0; i < 5; ++i)for (int j = 0; j <= i; ++j)pins[i][j] = that.pins[i][j];}public List<GameBoard> possibleBoards() {List<GameBoard> boards = new ArrayList<GameBoard>();for (int i = 0; i < 5; ++i)for (int j = 0; j <= i; ++j) {Position start = new Position(i,j);List<Move> possibleMoves = Moves.getMoves(start);for (Move move : possibleMoves) {if (validMove(move))boards.add(jump(move));}}return boards;}public boolean validMove(Move move) {if (!pins[move.getStart().getRow()][move.getStart().getCol()]) // empty startreturn false;if (!pins[move.getJump().getRow()][move.getJump().getCol()]) // empty jump overreturn false;if (pins[move.getEnd().getRow()][move.getEnd().getCol()]) // filled in endreturn false;return true;}public GameBoard jump(Move move) {GameBoard gb = new GameBoard(this);gb.pins[move.getStart().getRow()][move.getStart().getCol()] = false;gb.pins[move.getJump().getRow()][move.getJump().getCol()] = false;gb.pins[move.getEnd().getRow()][move.getEnd().getCol()] = true;return gb;}public boolean finalBoard() {int remainingPins = 0;for (int i = 0; i < 5; ++i)for (int j = 0; j <= i; ++j) if (pins[i][j]) {remainingPins++;if (remainingPins > 1) // optimize, early out, more than 1 pin is not final boardreturn false;}return remainingPins == 1;} public int toInt() {int ret = 0;for (int i = 0; i < 5; ++i)for (int j = 0; j <= i; ++j) {ret *= 2;if (pins[i][j]) {ret |= 1;}}return ret;}public String toString() {StringBuffer sb = new StringBuffer();for (int i = 0; i < 5; ++i) {for (int s = 4-i; s > 0; --s)sb.append(" ");for (int j = 0; j <= i; ++j) {sb.append(pins[i][j] ? 'X' : 'O').append(" ");}sb.append("\n");}
// sb.append(toInt()+ "\n");return sb.toString();}
}
Move.java:移动的坐标指向类
package com.game.board;public class Move {private Position start;private Position jump;private Position end;public Move(Position start, Position jump, Position end) {this.start = start;this.jump = jump;this.end = end;}public Position getStart() { return start; }public Position getJump() { return jump; }public Position getEnd() { return end; }public String toString() {StringBuffer sb = new StringBuffer();sb.append("{"+start);sb.append(","+jump);sb.append(","+end+ "}");return sb.toString();}
}
Moves.java:将所有起始点可以移动的方向全部列举并放入map集合中
package com.game.board;import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;public class Moves {private static Map<Position,List<Move>> validMoves = new HashMap<Position,List<Move>>();static {/* * 0,0 * 1,0 1,1* 2,0 2,1 2,2* 3,0 3,1 3,2 3,3* 4,0 4,1 4,2 4,3 4,4* */Position start;start = new Position(0,0); validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(1,0), new Position(2,0)));validMoves.get(start).add(new Move(start, new Position(1,1), new Position(2,2)));start = new Position(1,0);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(2,0), new Position(3,0)));validMoves.get(start).add(new Move(start, new Position(2,1), new Position(3,2)));start = new Position(1,1);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(2,1), new Position(3,1)));validMoves.get(start).add(new Move(start, new Position(2,2), new Position(3,3))); /* * 0,0 * 1,0 1,1* 2,0 2,1 2,2* 3,0 3,1 3,2 3,3* 4,0 4,1 4,2 4,3 4,4* */ start = new Position(2,0);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(1,0), new Position(0,0)));validMoves.get(start).add(new Move(start, new Position(2,1), new Position(2,2)));validMoves.get(start).add(new Move(start, new Position(3,0), new Position(4,0)));validMoves.get(start).add(new Move(start, new Position(3,1), new Position(4,2)));start = new Position(2,1);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(3,1), new Position(4,1)));validMoves.get(start).add(new Move(start, new Position(3,2), new Position(4,3)));start = new Position(2,2);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(1,1), new Position(0,0)));validMoves.get(start).add(new Move(start, new Position(2,1), new Position(2,0)));validMoves.get(start).add(new Move(start, new Position(3,2), new Position(4,2)));validMoves.get(start).add(new Move(start, new Position(3,3), new Position(4,4))); /* * 0,0 * 1,0 1,1* 2,0 2,1 2,2* 3,0 3,1 3,2 3,3* 4,0 4,1 4,2 4,3 4,4* */ start = new Position(3,0);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(2,0), new Position(1,0)));validMoves.get(start).add(new Move(start, new Position(3,1), new Position(3,2))); start = new Position(3,1);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(2,1), new Position(1,1)));validMoves.get(start).add(new Move(start, new Position(3,2), new Position(3,3)));start = new Position(3,2);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(2,1), new Position(1,0)));validMoves.get(start).add(new Move(start, new Position(3,1), new Position(3,0))); start = new Position(3,3);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(2,2), new Position(1,1)));validMoves.get(start).add(new Move(start, new Position(3,2), new Position(3,1))); /* * 0,0 * 1,0 1,1* 2,0 2,1 2,2* 3,0 3,1 3,2 3,3* 4,0 4,1 4,2 4,3 4,4* */ start = new Position(4,0);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(3,0), new Position(2,0)));validMoves.get(start).add(new Move(start, new Position(4,1), new Position(4,2))); start = new Position(4,1);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(3,1), new Position(2,1)));validMoves.get(start).add(new Move(start, new Position(4,2), new Position(4,3))); start = new Position(4,2);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(3,1), new Position(2,0)));validMoves.get(start).add(new Move(start, new Position(3,2), new Position(2,2)));validMoves.get(start).add(new Move(start, new Position(4,1), new Position(4,0)));validMoves.get(start).add(new Move(start, new Position(4,3), new Position(4,4)));start = new Position(4,3);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(3,2), new Position(2,1)));validMoves.get(start).add(new Move(start, new Position(4,2), new Position(4,1)));start = new Position(4,4);validMoves.put(start, new ArrayList<Move>()); validMoves.get(start).add(new Move(start, new Position(3,3), new Position(2,2)));validMoves.get(start).add(new Move(start, new Position(4,3), new Position(4,2))); }public static List<Move> getMoves(Position position) {if (!validMoves.containsKey(position))throw new RuntimeException("Invalid position: " + position);return validMoves.get(position);}public String toString() {return validMoves.toString();}
}
position.java:坐标类
package com.game.board;public class Position {int row;int col;public Position(int row, int col) {this.row = row;this.col = col;}public int getRow() { return row; }public int getCol() { return col; }public String toString() {return "[" + row + "," + col + "]";}public int hashCode() {int result = 17;result = 37*result + row;result = 37*result + col;return result;}public boolean equals(Object other) {if (!(other instanceof Position))return false;Position that = (Position) other;if (this.row != that.row)return false;return this.col == that.col;}
}
GameTree.java:以树的形式保存遍历的所有路径
package com.game.play;import java.util.List;
import java.util.ArrayList;import com.game.board.GameBoard;public class GameTree {GameTree level;GameBoard gb;List<GameTree> children = new ArrayList<GameTree>();public GameTree(GameBoard gb) {this.gb = gb;}public void addChild(GameTree child) {children.add(child);}public GameBoard getGameBoard() { return gb; }public boolean hasChildren() {return children.size() > 0;}public GameTree getFirstChild() {return children.get(0);}public void removeFirstChild() {children.remove(0);}public int numChildren() {return children.size();}
}
Play.java:通过DFS搜索所有可能的路径
package com.game.play;import java.io.IOException;
import java.util.List;
import java.io.BufferedReader;
import java.io.InputStreamReader;import com.game.board.GameBoard;public class Play {GameBoard startBoard;public Play(String[] args) throws IOException {if (args.length == 0) {int n1,n2;BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in));System.out.println("Name: samudra ");System.out.println("......................................");System.out.println("Enter the position of the hole:");n1=Integer.parseInt( stdin.readLine());n2=Integer.parseInt( stdin.readLine());init(n1,n2);}elseinit(Integer.parseInt( args[0]),Integer.parseInt( args[1]));}private void init(int row, int col) {startBoard = new GameBoard(row, col);}//DFS functionpublic void DFS() {GameTree root = new GameTree(startBoard);for (GameBoard nextBoard : startBoard.possibleBoards()) {GameTree nextNode = new GameTree(nextBoard);if (play(nextBoard, nextNode))root.addChild(nextNode);}printWinningGame(root); }// to iterate is human, to recurse divine// print game board at each node on the way down, removing the printed child on the way upprivate void printWinningGame(GameTree parent) {System.out.println(parent.getGameBoard());if (parent.numChildren() > 0) {GameTree nextNode = parent.getFirstChild(); printWinningGame(nextNode); // recurseif (nextNode.numChildren() == 0) parent.removeFirstChild();} else {System.out.println("===============================================");}}// chase all possible boardsprivate boolean play(GameBoard gb, GameTree parent) {if (gb.finalBoard()) // remember this path was a winning pathreturn true;List<GameBoard> nextBoards = gb.possibleBoards();boolean found = false;for (GameBoard nextBoard : nextBoards) {GameTree nextNode = new GameTree(nextBoard);if (play(nextBoard, nextNode)) { // recursefound = true;parent.addChild(nextNode);}}return found;}}
PegBord.java:主方法
package com.game.main;import java.io.IOException;import com.game.play.Play;public class PegBoard {/**
* @param args
*/public static void main(String[] args) throws IOException {Play play = new Play(args);play.DFS();}}
运行结果展示:
......................................
Enter the position of the hole:
2
1
X
X X
X O X
X X X X
X X X X X
X
X X
X X X
X O X X
X O X X X
X
X X
X X X
X X O O
X O X X X
X
O X
X O X
X X X O
X O X X X
X
O O
X O O
X X X X
X O X X X
X
X O
O O O
O X X X
X O X X X
O
O O
X O O
O X X X
X O X X X
O
O O
X O O
O X X X
X X O O X
O
O O
O O O
O O X X
X X X O X
O
O O
O O O
O O X X
X O O X X
O
O O
O O X
O O X O
X O O X O
O
O O
O O O
O O O O
X O X X O
O
O O
O O O
O O O O
X X O O O
O
O O
O O O
O O O O
O O X O O
===============================================
Triangle Peg Solitaire(孔明棋)相关推荐
- Go语言解决孔明棋的玩法(加深对for循环的认识)
对于for循环,在 Go语言零基础入门,捕获错误.slice切片.for循环.test 中也有介绍,大家都很熟悉,一般是三部分组成:初始化,条件表达式,后置语句,如下: func main() {fo ...
- 通过python递归来解决孔明棋问题
孔明棋大家应该都不陌生.(好吧可能不一定) 简单来讲,是一种规则简单,但是过程并不见得容易,可以一个人玩的棋. 他有还一个有趣的名字:法国跳棋独立钻石. 我上手的是vx某小程序.玩法比最经典的32颗棋 ...
- 我用VB做的孔明棋游戏
我用VB做的孔明棋游戏 附源码 http://download1.csdn.net/down3/20070530/30200905916.rar
- 类似孔明棋,寻找棋局中到达目标点的最短路径(深搜和广搜)
主题内容: 有个游戏玩法很类似孔明棋. 其游戏的原始规则如下: 原始棋盘为这样: 假设0为空格 1为棋子 0000000 0000000 0000000 0000000 1111111 1111111 ...
- 类孔明棋 c语言实验,深度优先搜索中的重叠子结果的优化问题
前几天帮朋友写一个类孔明棋的算法, 上题 5*5的棋盘 .表示没棋子 o表示有棋子 如: ooooo ooooo oo.oo ooooo ooooo 走法和孔明的走法一样 开始直接 ...
- Python小游戏——孔明棋
Python小游戏--孔明棋 规则简介 孔明棋又叫法国独立钻石,是一种单人棋,下法规则简单,棋子只能跳过相邻的棋子到空位上,并且把被跳过的棋子吃掉.棋子可以沿格线横.纵方向跳,但是不能斜跳,当棋盘内所 ...
- URAL 1051 跳跳棋(孔明棋)(加强版) 数学找规律(较弱哦)
跳跳棋(加强版) 问题描述 hty想到最近出过一道1*N的跳跳棋游戏,于是他想是否2维也能有很好的方法呢?于是有了下面这道题,题目如下:在一个无限大的棋盘的格子上有一些棋子,这些棋子构成一个M*N的矩 ...
- [构造 找规律 孔明棋] Ural 1051 Simple Game on a Grid
论文:俞鑫--棋盘中的棋盘--浅谈棋盘的分割思想 证明篇幅太长就不弄过来了 #include<cstdio>int main(){int n,m,ans;freopen("t.i ...
- 独立钻石棋游戏设计制作(C语言)
独立钻石棋游戏设计制作(C语言) 我是编程爱好者.早期使用windows时就被扫雷游戏,钻石棋游戏,红心大战游戏迷住.相信大家也都玩过吧.在学习VB6编程时就编制过钻石棋和红心大战那样的纸牌游戏.都是 ...
最新文章
- 电信的 DNS 服务器地址
- Go gin静态文件的使用、自定义模板渲染器
- springboot @RequestBody 接收字符串
- dojo/request模块整体架构解析
- linux安全模式改文件,嵌入式Linux的安全模式设计 - 嵌入式操作系统 - 电子发烧友网...
- 警告—系统—srv—2013—无
- vs2017 js cordova + dotnet core 开发app
- python 测试开发请关注这个新框架
- dx绘制2d图像_【3D建模】聊聊2D动画软件
- 华为鸿蒙巴龙麒麟,华为5G新机强势曝光:麒麟985+巴龙5000+鸿蒙系统,颜值性能炸裂...
- spine怎么取消版本升级_设置 - Spine用户指南
- party_bid_core总结
- Google加速移动页面(AMP)简介
- HTML 媒体、表单和音视频笔记
- 新手向:如何用python打开网址
- sap的清账是什么意思_SAP清账的高手剖析
- 微信关注即可使用 Wi-Fi,取消关注即断网的路由器实现的流程原理以及步骤
- Bit(位)与Byte(字节)的区别
- 基石为勤能补拙的迷宫之旅——第一天(计算机硬件和操作系统)
- 最近几年的国内开源软件侵权事件
热门文章
- Mac下使用Xquartz连接CentOS的Xdm服务器
- SDCC 2016系列多站回顾:精彩集锦 百家争鸣(附PPT下载)
- oracle默认表达式uuid,Oracle中生成uuid的方法
- 鼠标精灵对码软件_Photo Frame 图片编辑软件(相框精灵)
- 停车场收费管理系统/停车场管理系统的设计与实现
- 12.1-12.8 计算机网络课堂笔记
- 在软件开发中实施人工智能和敏捷管理的9种方法
- 如何快速制作彩色二维码图片?
- 【Discuz】dz3.2论坛搬家心得
- MySQL 案例实战--MySQL 数据库 之 冷备份