五子棋的规则大家肯定都了解,也是大家在百忙之中娱乐的一部分,也都在网上玩过五子棋的游戏,那么大家有没有想过自己编写一个五子棋游戏呢。我们用Python简单实现一下,为了方便大家理解逻辑,这里咱们就直接在控制台输出,省掉前端页面的代码。
先上效果图
输入x, y坐标 即可开始下棋
五子连珠,游戏结束
接下来,上代码 https://github.com/LongXvng/gobang
java实现代码如下:
import java.util.Scanner;
public class GoBang {
// 棋盘宽高
public static final int WIDTH = 16, HEIGHT = 16;
// 棋子状态
public static final String BLANK = "_";
public static final String BLACK = "●";
public static final String WHITE = "○";
// 游戏状态
public static final int GAME_TYPE_CLOSE = 0;
public static final int GAME_TYPE_REGRET = 1;
public static final int GAME_TYPE_JUMP = 2;
// 判断连珠增量 [横向 纵向 右下到左上 左下到右上]
public static int[][] direction;
// 棋盘
public static String[][] chessboard;
// 最后一步落子位置 [x, y, chessman]
public static Object[] lastJump;
// 接收用户输入
public static Scanner scanner;
static {
direction = new int[][]{{0, 1}, {1, 0}, {1, 1}, {1, -1}};
chessboard = new String[WIDTH][HEIGHT];
scanner = new Scanner(System.in);
}
public static void init() {
for (int x = 0; x < WIDTH; x++) {
for (int y = 0; y < HEIGHT; y++) {
if (x == 0) {
chessboard[x][y] = Integer.toHexString(x);
} else {
if (y == 0) {
chessboard[x][y] = Integer.toHexString(y);
} else {
chessboard[x][y] = BLANK;
}
}
}
}
}
public static void paint() {
for (String[] line : chessboard) {
for (String x : line) {
System.out.print(x + " ");
}
System.out.println();
}
}
public static int[] getInput(int user) {
while (true) {
System.out.println("\n* 落子格式:x(num), y(num) 悔棋:regret 退出:quit");
System.out.println(String.format("%s(%s)玩家 请落子>", user == 0 ? "A" : "B", user == 0 ? BLACK : WHITE));
String inputStr = scanner.next();
if ("quit".equals(inputStr.toLowerCase()) || "exit".equals(inputStr.toLowerCase())) {
return new int[]{GAME_TYPE_CLOSE, 0, 0};
}
if ("regret".equals(inputStr.toLowerCase())) {
chessboard[(int) lastJump[0]] [(int) lastJump[1]] = BLANK;
return new int[]{GAME_TYPE_REGRET, 0, 0};
}
if (!inputStr.matches("[0-9a-fA-F][\\s]*[,,][\\s]*[0-9a-fA-F]")) {
System.out.println("输入格式错误!请重新落子");
continue;
}
String[] locations = inputStr.split(",");
int x, y;
if (locations.length == 2) {
x = Integer.parseInt(locations[0]);
y = Integer.parseInt(locations[1]);
} else {
locations = inputStr.split(",");
x = Integer.parseInt(locations[0]);
y = Integer.parseInt(locations[1]);
}
return new int[]{GAME_TYPE_JUMP, x, y};
}
}
public static boolean jump(int _x, int _y, int _user) {
if (!BLANK.equals(chessboard[_x][_y])) {
System.out.println("该位置已有棋子!请重新落子");
return false;
}
chessboard[_x][_y] = _user == 0 ? BLACK : WHITE;
lastJump = new Object[]{_x, _y, chessboard[_x][_y]};
return true;
}
public static Object[] checkWin() {
if (lastJump == null || lastJump.length == 0) {
return new Object[]{false, 0};
}
int last_x = (int) lastJump[0];
int last_y = (int) lastJump[1];
String chessman = (String) lastJump[2];
// 横向 纵向 右下到左上 左下到右上
for (int[] offset : direction) {
Object[] result = calDirection(last_x, last_y, offset[0], offset[1], chessman);
boolean _isWin = (boolean) result[0];
if (_isWin) {
return result;
}
}
return new Object[]{false, 0};
}
public static Object[] calDirection(int _x, int _y, int offset_x, int offset_y, String _chessman) {
int count = 0;
while (true) {
if (_x > 1 && _x < WIDTH && _y > 1 && _y < HEIGHT) {
_x += offset_x;
_y += offset_y;
if (!chessboard[_x][_y].equals(_chessman)) {
break;
}
} else {
break;
}
}
while (true) {
if (_x > 1 && _x < WIDTH && _y > 1 && _y < HEIGHT) {
_x += -1 * offset_x;
_y += -1 * offset_y;
if (chessboard[_x][_y].equals(_chessman)) {
count += 1;
if (count >= 5) {
break;
}
} else {
break;
}
} else {
break;
}
}
return new Object[]{count == 5, BLACK.equals(_chessman) ? 0 : 1};
}
public static void main(String[] args) {
int i = 0;
init();
while (true) {
paint();
Object[] result = checkWin();
boolean isWin = (boolean) result[0];
int winUser = (int) result[1];
if (!isWin) {
int user = i % 2;
int[] inputs = getInput(user);
int gameType = inputs[0];
int x = inputs[1];
int y = inputs[2];
if (gameType == GAME_TYPE_CLOSE) {
break;
} else if (gameType == GAME_TYPE_REGRET) {
i -= 1;
continue;
}
if (jump(x, y, user)) {
i += 1;
}
} else {
System.out.println(String.format("游戏结束! %s(%s)玩家获胜 双方落子%d手", winUser == 0 ? "A" : "B", winUser == 0 ? BLACK : WHITE, i));
break;
}
}
}
}
python实现代码如下:
import re
# 棋盘宽高
WIDTH, HEIGHT = 16, 16
# 棋子状态
BLANK = '_'
BLACK = '●'
WHITE = '○'
# 游戏状态
GAME_TYPE_CLOSE = 0
GAME_TYPE_REGRET = 1
GAME_TYPE_JUMP = 2
# 判断连珠增量 [横向 纵向 右下到左上 左下到右上]
direction = [[0, 1], [1, 0], [1, 1], [1, -1]]
# 棋盘 [16][16]
chessboard = []
# 最后一步落子位置 [x, y, user]
lastJump = []
def init():
global chessboard
chessboard = [[hex(y)[2] if x == 0 else hex(x)[2] if y == 0 else BLANK for x in range(0, WIDTH)] for y in
range(0, HEIGHT)]
def paint():
print(*(" ".join(chessboard[i]) for i in range(WIDTH)), sep='\n')
def getInput(_user):
while True:
print("\n* 落子格式:x(num), y(num) 悔棋:regret 退出:quit")
inputStr = input("{}玩家 请落子>".format("A(%s)" % BLACK if _user == 0 else "B(%s)" % WHITE))
if "quit" == inputStr.lower() or "exit" == inputStr.lower():
return [GAME_TYPE_CLOSE, 0, 0]
if "regret" == inputStr.lower():
chessboard[lastJump[0]][lastJump[1]] = BLANK
return [GAME_TYPE_REGRET, 0, 0]
if not re.match(r'[0-9a-fA-F][\s]*[,,][\s]*[0-9a-fA-F]', inputStr):
print("输入格式错误!请重新落子")
continue
locations = inputStr.split(",")
if len(locations) == 2:
x = int(locations[0], 16)
y = int(locations[1], 16)
else:
locations = inputStr.split(",")
x = int(locations[0], 16)
y = int(locations[1], 16)
return [GAME_TYPE_JUMP, x, y]
def jump(_x, _y, _user):
global lastJump
if chessboard[_x][_y] != BLANK:
print("该位置已有棋子!请重新落子")
return False
chessboard[_x][_y] = BLACK if _user == 0 else WHITE
lastJump = [_x, _y, chessboard[_x][_y]]
return True
def checkWin():
global lastJump
if not len(lastJump):
return [False, 0]
last_x, last_y, chessman = lastJump
# 横向 纵向 右下到左上 左下到右上
for offset_x, offset_y in direction:
_isWin, _winUser = calDirection(last_x, last_y, offset_x, offset_y, chessman)
if _isWin:
return [_isWin, _winUser]
return [False, 0]
def calDirection(_x, _y, offset_x, offset_y, _chessman):
count = 0
while True:
if 1 < _x < WIDTH and 1 < _y < HEIGHT:
_x += offset_x
_y += offset_y
if chessboard[_x][_y] != _chessman:
break
else:
break
while True:
if 1 < _x < WIDTH and 1 < _y < HEIGHT:
_x += -1 * offset_x
_y += -1 * offset_y
if chessboard[_x][_y] == _chessman:
count += 1
if count >= 5:
break
else:
break
else:
break
return [True if count == 5 else False, 0 if _chessman == BLACK else WHITE]
i = 0
init()
while True:
paint()
isWin, winUser = checkWin()
if not isWin:
user = i % 2
gameType, x, y = getInput(user)
if gameType == GAME_TYPE_CLOSE:
break
elif gameType == GAME_TYPE_REGRET:
i -= 1
continue
if jump(x, y, user):
i += 1
else:
print("游戏结束! {}玩家获胜 双方落子{}手".format("A(%s)" % BLACK if winUser == 0 else "B(%s)" % WHITE, i))
break