开篇前言
前面12篇文章一起学习了python入门最最基础的基础知识,哈哈。今天这篇文章一起利用这些知识实现一个五子棋小游戏。以便巩固学习下,再就是提高下兴趣。话不多说,开始吧。
视频演示
先来看下最后的游戏进行视频是要做成什么样的。
五子棋游戏过程演示视频
主要思路
上述视频可以看到,结果在控制台中打印。主要思路:
- 棋盘是个二维列表,默认二维列表中所有元素都为0,两个玩家下棋,会修改二维列表的值。每个玩家修改的值是固定的(例如默认全是0,玩家A改为1,玩家B改为-1;
- 需要一个打印方法,该方法里根据二维列表中的值打印不同的图案到控制台,以区分未落子坐标,玩家A落子,玩家B落子。
- 程序运行需要初始化二维列表,赋默认值0,需要循环让玩家输入棋盘中的坐标,以修改二维列表中的值,此处需要一个落子方法,该方法中各种判断完,需要对应玩家去修改对应坐标的值;
- 需要规定并判断用户输入格式是否满足规定,例如提示信息中的1,2表示第一行第二列落子。用户可以随便输入,需要判断输入是否符合规定;
- 在用户输入正确的情况下,需要判断位置是否已经落子,如果落子,或者第3步说的输入错误,这一步不能算作正常落子步数;
- 需要判断玩家是否胜利,按照五子棋的横、竖、两个对角斜方向,只要任意有5个相同颜色的棋子连成线则游戏结束,并且打印谁赢了,在游戏过程中提示第几手完成,轮到玩家A或玩家B。此处需要方法,判断二维列表中,横竖斜是否有连续相同的5个数字,如果有则游戏结束。
- 实现主方法中的循环调用
代码实现
在上述步骤开始前,可以想到,需要几个全局变量,以控制游戏进程。
# 棋盘大小,12乘12的棋盘大小,修改这里可以自己定义棋盘大小
SIZE = 12
# 游戏是否结束,控制循环,True表示循环还在继续,游戏没结束
OVER = True
# 记录第几次落子,控制台打印第几手落子
ICOUNT = 1
# 游戏结果判断,不同数值表示不同情况。默认值0,表示游戏还没结束
RESULT = 0
# 棋盘数组
board_list = []
现在根据上述思路,一步一步看。
- 第一步:初始化列表
这里很简单,只需要创建一个SIZE长宽的二维列表赋值给全局变量board_list 即可。
#初始化棋盘,默认二维数组元素值全是0
def initBoard():
for i in range(SIZE):
board_list.append([i * 0 for i in range(SIZE)])
return board_list
- 第二步:尝试打印这个二维列表
需要注意的是,怎么打印?这里规定:
1.二维列表中默认值 0打印:+
2.二维列表中默认值 1打印:●
3.二维列表中默认值-1打印:○
打印方法只负责根据数值打印即可。
# 打印棋盘,-1打印● 1打印○ 0打印默认 +
def printBoard():
for i in board_list:
for j in i:
print(" +" if j == 0 else "●" if j == -1 else "○", end="")
print()
- 第三步:玩家落子
先不考虑玩家多次落子,先只实现一步落子方法,再循环这个方法去实现两个玩家在循环落子即可。
这个方法中需要:
1、玩家输入坐标;
2、提示信息,告诉玩家是玩家A还是B,输入格式,提示该谁落子等信息。
其中使用到了判断玩家输入格式是否正确的方法,是否某个玩家已经取胜的方法。因为在每一次落子,都需要上述判断。玩家是不是输入错误了,是不是输入的坐标已经有棋子了,是不是落子后胜利了等等。
def putPiece(index):
# 将全局变量引入到方法
global ICOUNT
global OVER
global RESULT
# 第一二手提醒玩家身份 棋手A或棋手B
if ICOUNT <= 2:
print("记住你是棋手A" if ICOUNT == 1 else "记住你是棋手B")
# 判断玩家输入格式是否正确
if isCorrectInput(index):
indexX ,indexY = index.split(",")
# 判断是否该位置已经落过棋子
if board_list[int(indexX) - 1][int(indexY) - 1] == 0 :
if ICOUNT % 2 == 0:
print("第" + str(ICOUNT) + "手落完,轮到棋手A落子")
#棋手B落子数组记录值为1
board_list[int(indexX) - 1][int(indexY) - 1] = 1
else:
print("现第"+str(ICOUNT) + "手落完,轮到棋手B落子")
# 棋手B落子数组记录值为-1
board_list[int(indexX) - 1][int(indexY) - 1] = -1
# 此处待添加判断是否5子成线方法
else:
#当用户输入位置已经落子,当前步不算ICOUNT需要减1
ICOUNT -= 1
print("该位置已经落子,请重新落子")
printBoard()
# 待添加判断是否5子成棋情况
res = get_result()
if res in [-1,1,2]:
OVER = False
RESULT = res
else:
# 当用户输入位置不正确,当前步不算ICOUNT需要减1
ICOUNT -= 1
print("输入的棋子位置不正确,请重新输入!")
- 第四步:判断玩家输入格式正确否?
这里这个方法,只需判断
1、玩家输入的格式是不是带半角逗号,以及把半角逗号去除后是不是都是由数字组成的。
2、按照半角逗号拆分后,获得两个数组(对应二维列表中的X轴Y轴)是否都是大于等于1且小于SIZE,棋盘的最大长度。
# 用户输入时需要判断用户输入格式是否正确,
def isCorrectInput(s) -> bool:
res = False
if "," in s and str(s).replace(",","").isnumeric():
indexX, indexY = str(s).split(",")
if int(indexX) >= 1 and int(indexX) <= SIZE and int(indexY) >= 1 and int(indexY) <= SIZE:
res = True
return res
- 第五步:实现判断是否已取胜
这个方法中需要判断是否玩家落子后,这次落子已经取胜。
五子棋取胜有4种排列方式:
1、横排连续5个
2、纵排连续5个
3、左上到右下斜排连续5个
4、右上到左下斜排连续5个
判断二维列表中是否有上述4种情况的连续5个相同数字即可
每次落子,都需要调用此方法,每次此方法去判断会有结果:
1、这次落子有玩家取胜了,修改全局变量OVER = False RESULT=1 或 -1(两个值以区分是A赢还是B赢);
2、这次落子没有玩家取胜,OVER不变,RESULT还是默认值0,游戏继续;
3、这次落子后,二维列表中已经没有默认值0,表示全部位置都被下满了。和棋平局,OVER = False,RESULT = 2
def get_result():
"""判断游戏的结局。0为游戏进行中,1为玩家B获胜,-1为玩家A获胜,2为平局"""
# 1. 判断是否纵向连续五子
for x in range(SIZE - 4):
for y in range(SIZE):
if board_list[x][y] == 1 and board_list[x + 1][y] == 1 and board_list[x + 2][y] == 1 and board_list[x + 3][y] == 1 and board_list[x + 4][y] == 1:
return 1
if board_list[x][y] == -1 and board_list[x + 1][y] == -1 and board_list[x + 2][y] == -1 and board_list[x + 3][y] == -1 and board_list[x + 4][y] == -1:
return -1
# 2. 判断是否横向连续五子
for x in range(SIZE):
for y in range(SIZE - 4):
if board_list[x][y] == 1 and board_list[x][y + 1] == 1 and board_list[x][y + 2] == 1 and board_list[x][y + 3] == 1 and board_list[x][y + 4] == 1:
return 1
if board_list[x][y] == -1 and board_list[x][y + 1] == -1 and board_list[x][y + 2] == -1 and board_list[x][y + 3] == -1 and board_list[x][y + 4] == -1:
return -1
# 3. 判断是否横向连续五子
for x in range(SIZE - 4):
for y in range(SIZE - 4):
if board_list[x][y] == 1 and board_list[x + 1][y + 1] == 1 and board_list[x + 2][y + 2] == 1 and board_list[x + 3][y + 3] == 1 and board_list[x + 4][y + 4] == 1:
return 1
if board_list[x][y] == -1 and board_list[x + 1][y + 1] == -1 and board_list[x + 2][y + 2] == -1 and board_list[x + 3][y + 3] == -1 and board_list[x + 4][y + 4] == -1:
return -1
# 4. 判断是否横向连续五子
for x in range(SIZE - 4):
for y in range(SIZE - 4):
if board_list[x + 4][y] == 1 and board_list[x + 3][y + 1] == 1 and board_list[x + 2][y + 2] == 1 and board_list[x + 1][y + 3] == 1 and board_list[x][y + 4] == 1:
return 1
if board_list[x + 4][y] == -1 and board_list[x + 3][y + 1] == -1 and board_list[x + 2][y + 2] == -1 and board_list[x + 1][y + 3] == -1 and board_list[x][y + 4] == -1:
return -1
# 5. 判断是否为平局
for x in range(SIZE):
for y in range(SIZE):
if board_list[x][y] == 0: # 棋盘中还有剩余的格子,不能判断为平局
return 0
# 6.平局
return 2
- 第六步:主方法
在主方法中实现初始化棋盘,打印初始化的棋盘,循环调用落子方法 和 最后游戏结果的判断打印即可。
if __name__ == '__main__':
print("欢迎来到五子棋游戏")
initBoard()
printBoard()
while OVER:
index = input("请输入要下棋子位置,例如 1,2表示在第一行,第二列下一个棋子:")
putPiece(index)
ICOUNT += 1
player = "B" if RESULT == 1 else "A"
print("经过" + str(ICOUNT)+ "手后,恭喜棋手"+ player +"获得胜利!!!" if RESULT != 2 else "平局")
完整代码
# 棋盘大小
SIZE = 12
# 是否停止落子
OVER = True
# 记录第几次落子,控制台打印第几手落子
ICOUNT = 1
# 游戏结果
RESULT = 0
# 棋盘数组
board_list = []
#初始化棋盘,默认二维数组元素值全是0
def initBoard():
for i in range(SIZE):
board_list.append([i * 0 for i in range(SIZE)])
return board_list
# 打印棋盘,-1打印● 1打印○ 0打印默认 +
def printBoard():
for i in board_list:
for j in i:
print(" +" if j == 0 else "●" if j == -1 else "○", end="")
print()
# 用户输入时需要判断用户输入格式是否正确,
def isCorrectInput(s) -> bool:
res = False
if "," in s and str(s).replace(",","").isnumeric():
indexX, indexY = str(s).split(",")
if int(indexX) >= 1 and int(indexX) <= SIZE and int(indexY) >= 1 and int(indexY) <= SIZE:
res = True
return res
def get_result():
"""判断游戏的结局。0为游戏进行中,1为玩家B获胜,-1为玩家A获胜,2为平局"""
# 1. 判断是否纵向连续五子
for x in range(SIZE - 4):
for y in range(SIZE):
if board_list[x][y] == 1 and board_list[x + 1][y] == 1 and board_list[x + 2][y] == 1 and board_list[x + 3][y] == 1 and board_list[x + 4][y] == 1:
return 1
if board_list[x][y] == -1 and board_list[x + 1][y] == -1 and board_list[x + 2][y] == -1 and board_list[x + 3][y] == -1 and board_list[x + 4][y] == -1:
return -1
# 2. 判断是否横向连续五子
for x in range(SIZE):
for y in range(SIZE - 4):
if board_list[x][y] == 1 and board_list[x][y + 1] == 1 and board_list[x][y + 2] == 1 and board_list[x][y + 3] == 1 and board_list[x][y + 4] == 1:
return 1
if board_list[x][y] == -1 and board_list[x][y + 1] == -1 and board_list[x][y + 2] == -1 and board_list[x][y + 3] == -1 and board_list[x][y + 4] == -1:
return -1
# 3. 判断是否横向连续五子
for x in range(SIZE - 4):
for y in range(SIZE - 4):
if board_list[x][y] == 1 and board_list[x + 1][y + 1] == 1 and board_list[x + 2][y + 2] == 1 and board_list[x + 3][y + 3] == 1 and board_list[x + 4][y + 4] == 1:
return 1
if board_list[x][y] == -1 and board_list[x + 1][y + 1] == -1 and board_list[x + 2][y + 2] == -1 and board_list[x + 3][y + 3] == -1 and board_list[x + 4][y + 4] == -1:
return -1
# 4. 判断是否横向连续五子
for x in range(SIZE - 4):
for y in range(SIZE - 4):
if board_list[x + 4][y] == 1 and board_list[x + 3][y + 1] == 1 and board_list[x + 2][y + 2] == 1 and board_list[x + 1][y + 3] == 1 and board_list[x][y + 4] == 1:
return 1
if board_list[x + 4][y] == -1 and board_list[x + 3][y + 1] == -1 and board_list[x + 2][y + 2] == -1 and board_list[x + 1][y + 3] == -1 and board_list[x][y + 4] == -1:
return -1
# 5. 判断是否为平局
for x in range(SIZE):
for y in range(SIZE):
if board_list[x][y] == 0: # 棋盘中还有剩余的格子,不能判断为平局
return 0
# 6.平局
return 2
def putPiece(index):
# 将全局变量引入到方法
global ICOUNT
global OVER
global RESULT
# 第一二手提醒玩家身份 棋手A或棋手B
if ICOUNT <= 2:
print("记住你是棋手A" if ICOUNT == 1 else "记住你是棋手B")
# 判断玩家输入格式是否正确
if isCorrectInput(index):
indexX ,indexY = index.split(",")
# 判断是否该位置已经落过棋子
if board_list[int(indexX) - 1][int(indexY) - 1] == 0 :
if ICOUNT % 2 == 0:
print("第" + str(ICOUNT) + "手落完,轮到棋手A落子")
#棋手B落子数组记录值为1
board_list[int(indexX) - 1][int(indexY) - 1] = 1
else:
print("现第"+str(ICOUNT) + "手落完,轮到棋手B落子")
# 棋手B落子数组记录值为-1
board_list[int(indexX) - 1][int(indexY) - 1] = -1
# 此处待添加判断是否5子成线方法
else:
#当用户输入位置已经落子,当前步不算ICOUNT需要减1
ICOUNT -= 1
print("该位置已经落子,请重新落子")
printBoard()
# 待添加判断是否5子成棋情况
res = get_result()
if res in [-1,1,2]:
OVER = False
RESULT = res
else:
# 当用户输入位置不正确,当前步不算ICOUNT需要减1
ICOUNT -= 1
print("输入的棋子位置不正确,请重新输入!")
if __name__ == '__main__':
print("欢迎来到五子棋游戏")
initBoard()
printBoard()
while OVER:
index = input("请输入要下棋子位置,例如 1,2表示在第一行,第二列下一个棋子:")
putPiece(index)
ICOUNT += 1
player = "B" if RESULT == 1 else "A"
print("经过" + str(ICOUNT)+ "手后,恭喜棋手"+ player +"获得胜利!!!" if RESULT != 2 else "平局")
最后总结
这个游戏中主要用到了python中的:
1、列表(添加修改,推导式等);
2、执行流程(if…else… while循环,三目表达式等);
3、方法定义,调用等
最最后,码字不易,喜欢的点个赞吧~