[教你做小游戏] 《五子棋》怎么判断输赢?你能5分钟交出代码吗?

本文介绍了如何在5分钟内实现《五子棋》的输赢判断算法,适合业务开发者快速解决此类问题。基本假设为仅最后一手棋决定胜负。解决方案包括5分钟方案和15分钟优化方案,详细描述了算法思路、注意事项,并提供了完整代码。
摘要由CSDN通过智能技术生成

我是HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。

1. 问题描述

《五子棋》游戏,如何判断输赢呢?

这个问题是不是很简单?适合给代码初学者练手。

但是如果你真的只想快速开发一个五子棋,常年混迹开发业务、多年没摸算法的你,的确可能会在这个问题上头疼。

因为目标不一样:代码初学者愿意花好几个小时在这上面优化算法,但业务开发者只想5分钟内解决掉这个问题。

今天,我们作为业务开发者,5分钟实现它。

输入

当前棋盘上的棋子分布信息,分布信息通常有2种存储方式,见上篇文章《《五子棋》怎么存棋局信息?》。本文采用的是文中2.6节的方案一

  • 用一个列表存储已落的棋子,列表顺序表明棋子顺序,列表每一项的值代表棋子的位置,值为0-224(刚好15*15=225个值),奇数位置是黑棋,偶数位置是白棋。

以这局为例:https://game.hullqin.cn/wzq/?p=000110112021303140

注意:网址参数中,是用15进制表示棋子的。每2位是一个棋子。

// 网址参数对应这样的输入数据:
const input = [0, 1, 15, 16, 30, 31, 45, 46, 60];
// 分别是 00 01 10 11 20 21 30 31 40 奇数位置是黑棋,偶数位置是白棋

1.png

输出

有3种可能:

  1. 黑棋赢
  2. 白棋赢
  3. 没人赢(游戏应该继续)

(当然也有诉求判断是否平局,但场景不多,本文不考虑这种判断是否平局的诉求。另外也因为我游戏中有认输功能,不会出现棋盘下满导致双方无法做任何操作的情况)

基本假设

有且仅有最后一手棋,导致某方五联珠胜利。

也就是说:

  • 如果最后一手是黑棋,那么当前白棋一定没赢,只需要判断黑棋是否赢,就知道输出是1还是3。
  • 如果最后一手是白棋,那么当前黑棋一定没赢,只需要判断白棋是否赢,就知道输出是2还是3。

这个基本假设,符合真实的五子棋场景。

2. 解决方案

2.1 五分钟方案

如果你觉得这个问题又简单又恶心,只想快速做完,可以这样做:

先找到最后一手棋的颜色,拿到该颜色棋子的集合:

const input = [0, 1, 15, 16, 30, 31, 45, 46, 60];
const pieces = input.filter((piece, index) => input.length % 2 !== index % 2);
console.log(pieces);

比如input.length是奇数,表明最后一手是黑棋,筛选出input的所有第偶数项(从0开始)都是黑棋。

然后遍历这个集合,看看它上下左右斜共8个方向,有没有5连珠,若有,则他赢;否则他没赢。

const input = [0, 1, 15, 16, 30, 31, 45, 46, 60];
const pieces = input.filter((piece, index) => input.length % 2 !== index % 2);
console.log(pieces);

const judge = (pieces) => {
   
  const pieceSet = new Set(pieces);
  for (let i = 0; i < pieces.length; i++) {
   
    const piece = pieces[i];
    if (piece % 15 >= 4 && pieceSet.has(piece - 1) && pieceSet.has(piece - 2) && pieceSet.has(piece - 3) && pieceSet.has(piece - 4)) return true;
    if (piece % 15 <= 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当然可以,以下是一个简单的五子棋游戏的代码示例: ```python import numpy as np def create_board(): board = np.zeros((15,15)) return board def is_valid_move(board, x, y): if x < 0 or x > 14 or y < 0 or y > 14: return False if board[x][y] != 0: return False return True def place_piece(board, x, y, color): board[x][y] = color def get_winner(board): # 检查横向 for i in range(15): for j in range(11): if board[i][j] == board[i][j+1] == board[i][j+2] == board[i][j+3] == board[i][j+4] != 0: return board[i][j] # 检查纵向 for i in range(11): for j in range(15): if board[i][j] == board[i+1][j] == board[i+2][j] == board[i+3][j] == board[i+4][j] != 0: return board[i][j] # 检查斜向 for i in range(11): for j in range(11): if board[i][j] == board[i+1][j+1] == board[i+2][j+2] == board[i+3][j+3] == board[i+4][j+4] != 0: return board[i][j] for i in range(11): for j in range(4, 15): if board[i][j] == board[i+1][j-1] == board[i+2][j-2] == board[i+3][j-3] == board[i+4][j-4] != 0: return board[i][j] return 0 def print_board(board): print(" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14") for i in range(15): row = str(i) + " " for j in range(15): if board[i][j] == 0: row += ". " elif board[i][j] == 1: row += "X " else: row += "O " print(row) def play_game(): board = create_board() player = 1 while True: print_board(board) print("Player", player, "turn") move = input("Enter x,y coordinates (q to quit): ") if move == "q": break x, y = move.split(",") x = int(x) y = int(y) if not is_valid_move(board, x, y): print("Invalid move, try again") continue place_piece(board, x, y, player) winner = get_winner(board) if winner != 0: print_board(board) print("Player", winner, "wins!") break player = 3 - player play_game() ``` 这个代码会创建一个 15x15 的棋盘,玩家可以轮流下棋,在棋盘上放置自己的棋子。当有五个相同颜色的棋子连接在一起时,该玩家获胜。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hull Qin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值