小编给大家分享一下用Python制作一个重力四子棋小游戏,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨方法吧!

新手学习Python,写第一个Python小游戏——四连环(重力四子棋)

游戏规则如下:

棋盘为8*6

玩家输入列号与电脑下四子棋,棋会随着重力下降

胜利方式是一行/一列/左右斜线连四颗棋子

分析:

拆分成了这几个部分,用自定义函数封装,便于修改:

·初始化

·棋盘显示

·玩家输入

·游戏运行

·判断胜利

引用库:random

第一部分:初始化

definit():globalboard#棋盘,二维列表globalrest_num#每一列剩余棋子数,一维整型列表globala#先手判定,整型globalreminded_line#未被填满列的记录,一维整型列表globalsymbol0#执棋方记录1,字典globalsymbol1#执棋方记录2,字典symbol1={"O":"玩家","X":"电脑"}symbol0={"X":"玩家","O":"电脑"}a=random.randint(0,2)reminded_line=[0,1,2,3,4,5,6,7]board=[["-"]*8foriinrange(6)]rest_num=[6foriinrange(8)]show(board)

这里初始化定义了一些之后用得到的变量

第二部分:棋盘显示

defshow(board):foriinrange(6):forjinrange(8):print(board[i][j],end="")print()

用索引下标的方式遍历棋盘并打印

第三部分:玩家输入

defplayerInput(rest_num):whileTrue:inp=int(input())-1#注意:列表起始于list[0]ifinpinrange(0,8):#符合8列ifrest_num[inp]>0:#该列有空余returninpelse:print("输入错误")else:print("输入错误")

输入用While True循环,直到输入正确

要判定输入的列号是否在1-8列内,且该列有空余!

第四部分:运行

先后手问题在主函数内用 if 判断初始化内全局变量a来执行不同顺序

四子棋的前三个回合不会分出胜负,因此拆分成前三个回合和剩余回合

这里可以算多此一举吧,前三次只是少了判断胜负

用 round3_0、round4_0 和 round3_1、round4_1 区分

游戏运行使用for次数循环,胜利提前结束即可

defround3_0():round_cout=0#回合计数foriinrange(3):round_cout+=1#回合+1print("\n===回合数"+str(round_cout)+"===")print("\n电脑")#常规的面板绘制#电脑下棋的列号#这里用从列表随机是为了不会出现该列已满无法下棋的情况robot_line=random.sample(reminded_line,1)[0]#电脑下棋的行号,记得要-1#因为重力下落,这里行号就是空余数量-1robot_height=rest_num[robot_line]-1#电脑下棋board[robot_height][robot_line]="O"#该列剩余-1rest_num[robot_line]-=1show(board)#显示棋盘print("\n轮到你了:")player_line=playerInput(rest_num)player_height=rest_num[player_line]-1board[player_height][player_line]="X"rest_num[player_line]-=1show(board)defround3_1():#同上,只是先后手顺序改变round_cout=0foriinrange(3):round_cout+=1print("\n===回合数"+str(round_cout)+"===")print("\n轮到你了:")player_line=playerInput(rest_num)player_height=rest_num[player_line]-1board[player_height][player_line]="O"rest_num[player_line]-=1show(board)print("\n电脑")robot_line=random.sample(reminded_line,1)[0]robot_height=rest_num[robot_line]-1board[robot_height][robot_line]="X"rest_num[robot_line]-=1show(board)defround4_0():round_cout=3#回合计数foriinrange(3,24):#共48个棋子,24个回合round_cout+=1print("\n===回合数"+str(round_cout)+"===")print("\n电脑")robot_line=random.sample(reminded_line,1)[0]robot_height=rest_num[robot_line]-1board[robot_height][robot_line]="O"rest_num[robot_line]-=1#如果该列已满,则在剩余列编号列表中移除,排除随机到该列ifrest_num[robot_line]==0:reminded_line.remove(robot_line)show(board)#!胜负判定!IsWinning(board,"O",symbol0)print("\n轮到你了:")player_line=playerInput(rest_num)player_height=rest_num[player_line]-1board[player_height][player_line]="X"rest_num[player_line]-=1ifrest_num[robot_line]==0:reminded_line.remove(robot_line)show(board)IsWinning(board,"X",symbol0)print("平局!")#最后分不出胜负就是平局defround4_1():round_cout=3foriinrange(3,24):round_cout+=1print("\n===回合数"+str(round_cout)+"===")print("\n轮到你了:")player_line=playerInput(rest_num)player_height=rest_num[player_line]-1board[player_height][player_line]="O"rest_num[player_line]-=1ifrest_num[player_line]==0:reminded_line.remove(player_line)show(board)IsWinning(board,"O",symbol1)print("\n电脑")robot_line=random.sample(reminded_line,1)[0]robot_height=rest_num[robot_line]-1board[robot_height][robot_line]="X"rest_num[robot_line]-=1ifrest_num[robot_line]==0:reminded_line.remove(robot_line)show(board)IsWinning(board,"X",symbol1)print("平局!")

第五部分:胜利判断

详细解释判定条件

胜利有四种情况:横4、竖4、左斜4、右斜4

因此继续封装成两种形式:直线、斜线进行判定

因为左斜和右斜是关于棋盘左右对称的

这里board_s就是对称棋盘

用 [::-1] 进行倒序

传入三个参数:棋盘、棋子类型(X/O)、执棋方记录

defIsWinning(board,chess_type,symbol):rowIsWinning(board,chess_type,symbol)leftSlashIsWinning(board,chess_type,symbol)board_s=[]foriinboard:board_s.append(i[::-1])#左右对称leftSlashIsWinning(board_s,chess_type,symbol)

========

直线判定:

defrowIsWinning(board,chess_type,symbol):#竖4forline_noinrange(8):forheight_noinrange(3):ifboard[height_no][line_no]==\board[height_no+1][line_no]==\board[height_no+2][line_no]==\board[height_no+3][line_no]==\chess_type:print("\n游戏结束!获胜的是:"+symbol[chess_type])exit(0)#横4forheight_noinrange(6):forline_noinrange(5):ifboard[height_no][line_no]==\board[height_no][line_no+1]==\board[height_no][line_no+2]==\board[height_no][line_no+3]==\chess_type:print("\n游戏结束!获胜的是:"+symbol[chess_type])exit(0)

首先下标索引遍历每一列

然后在每一列判定是否包含4个相同棋子

每一列得到前三行的棋子,之后再通过列下标不变,行下标递增获得四个棋子的坐标

横4的判断同理

========

难点

斜线判定:

斜线分左斜和右斜,左右是对称的,因此只用一种方法而将另一种判定换成将棋盘对称的操作

棋盘也是关于对角线可以对称的,也可以左右 + 对角线对称,从而转换成一种判定方式(棋盘左对角线左方左斜的情况),对棋盘操作统统化成一种

以下以左斜线判定为例子:

蓝色部分无法构成斜线,无需考虑

斜线有一个重要性质:坐标行号列号均相差正整数

因此只需要表示出下方绿色区域的棋子坐标就可以表示所有斜线:

(还有一种特殊情况)

只要循环表示出绿色区域内的坐标 通过行列递增即可表示斜线:

对于左上区域的坐标可以发现:

行号是1-3,而列号是1 ~ 行号

对于右下区域:

行号是4-6,列号是(行号+2) ~ 8

因此可以使用嵌套for循环表示

defleftSlashIsWinning(board,chess_type,symbol):#表示左上绿色部分forinit_heightinrange(3):forinit_lineinrange(init_height+1):ifboard[init_height][init_line]==\board[init_height+1][init_line+1]==\board[init_height+2][init_line+2]==\board[init_height+3][init_line+3]==\chess_type:print("\n游戏结束!获胜的是:"+symbol[chess_type])exit(0)#表示右下绿色部分forinit_heightinrange(3,6):forinit_lineinrange(init_height+2,8):ifboard[init_height][init_line]==\board[init_height-1][init_line-1]==\board[init_height-2][init_line-2]==\board[init_height-3][init_line-3]==\chess_type:print("\n游戏结束!获胜的是:"+symbol[chess_type])exit(0)#中间特殊情况forinit_heightinrange(3):init_line=init_height+1ifboard[init_height][init_line]==\board[init_height+1][init_line+1]==\board[init_height+2][init_line+2]==\board[init_height+3][init_line+3]==\chess_type:print("\n游戏结束!获胜的是:"+symbol[chess_type])exit(0)

完整代码:

importrandomdefinit():globalboardglobalrest_numglobalaglobalreminded_lineglobalsymbol0globalsymbol1symbol1={"O":"玩家","X":"电脑"}symbol0={"X":"玩家","O":"电脑"}a=random.randint(0,2)reminded_line=[0,1,2,3,4,5,6,7]board=[["-"]*8foriinrange(6)]rest_num=[6foriinrange(8)]show(board)defshow(board):foriinrange(6):forjinrange(8):print(board[i][j],end="")print()defIsWinning(board,chess_type,symbol):rowIsWinning(board,chess_type,symbol)leftSlashIsWinning(board,chess_type,symbol)board_s=[]foriinboard:board_s.append(i[::-1])leftSlashIsWinning(board_s,chess_type,symbol)defrowIsWinning(board,chess_type,symbol):forline_noinrange(8):forheight_noinrange(3):ifboard[height_no][line_no]==\board[height_no+1][line_no]==\board[height_no+2][line_no]==\board[height_no+3][line_no]==\chess_type:print("\n游戏结束!获胜的是:"+symbol[chess_type])exit(0)forheight_noinrange(6):forline_noinrange(5):ifboard[height_no][line_no]==\board[height_no][line_no+1]==\board[height_no][line_no+2]==\board[height_no][line_no+3]==\chess_type:print("\n游戏结束!获胜的是:"+symbol[chess_type])exit(0)defleftSlashIsWinning(board,chess_type,symbol):forinit_heightinrange(3):forinit_lineinrange(init_height+1):ifboard[init_height][init_line]==\board[init_height+1][init_line+1]==\board[init_height+2][init_line+2]==\board[init_height+3][init_line+3]==\chess_type:print("\n游戏结束!获胜的是:"+symbol[chess_type])exit(0)forinit_heightinrange(3,6):forinit_lineinrange(init_height+2,8):ifboard[init_height][init_line]==\board[init_height-1][init_line-1]==\board[init_height-2][init_line-2]==\board[init_height-3][init_line-3]==\chess_type:print("\n游戏结束!获胜的是:"+symbol[chess_type])exit(0)forinit_heightinrange(3):init_line=init_height+1ifboard[init_height][init_line]==\board[init_height+1][init_line+1]==\board[init_height+2][init_line+2]==\board[init_height+3][init_line+3]==\chess_type:print("\n游戏结束!获胜的是:"+symbol[chess_type])exit(0)defplayerInput(rest_num):whileTrue:inp=int(input())-1ifinpinrange(0,8):ifrest_num[inp]>0:returninpelse:print("输入错误")else:print("输入错误")defround3_0():round_cout=0foriinrange(3):round_cout+=1print("\n===回合数"+str(round_cout)+"===")print("\n电脑")robot_line=random.sample(reminded_line,1)[0]robot_height=rest_num[robot_line]-1board[robot_height][robot_line]="O"rest_num[robot_line]-=1show(board)print("\n轮到你了:")player_line=playerInput(rest_num)player_height=rest_num[player_line]-1board[player_height][player_line]="X"rest_num[player_line]-=1show(board)defround3_1():round_cout=0foriinrange(3):round_cout+=1print("\n===回合数"+str(round_cout)+"===")print("\n轮到你了:")player_line=playerInput(rest_num)player_height=rest_num[player_line]-1board[player_height][player_line]="O"rest_num[player_line]-=1show(board)print("\n电脑")robot_line=random.sample(reminded_line,1)[0]robot_height=rest_num[robot_line]-1board[robot_height][robot_line]="X"rest_num[robot_line]-=1show(board)defround4_0():round_cout=3foriinrange(3,24):round_cout+=1print("\n===回合数"+str(round_cout)+"===")print("\n电脑")robot_line=random.sample(reminded_line,1)[0]robot_height=rest_num[robot_line]-1board[robot_height][robot_line]="O"rest_num[robot_line]-=1ifrest_num[robot_line]==0:reminded_line.remove(robot_line)show(board)IsWinning(board,"O",symbol0)print("\n轮到你了:")player_line=playerInput(rest_num)player_height=rest_num[player_line]-1board[player_height][player_line]="X"rest_num[player_line]-=1ifrest_num[robot_line]==0:reminded_line.remove(robot_line)show(board)IsWinning(board,"X",symbol0)print("平局!")defround4_1():round_cout=3foriinrange(3,24):round_cout+=1print("\n===回合数"+str(round_cout)+"===")print("\n轮到你了:")player_line=playerInput(rest_num)player_height=rest_num[player_line]-1board[player_height][player_line]="O"rest_num[player_line]-=1ifrest_num[player_line]==0:reminded_line.remove(player_line)show(board)IsWinning(board,"O",symbol1)print("\n电脑")robot_line=random.sample(reminded_line,1)[0]robot_height=rest_num[robot_line]-1board[robot_height][robot_line]="X"rest_num[robot_line]-=1ifrest_num[robot_line]==0:reminded_line.remove(robot_line)show(board)IsWinning(board,"X",symbol1)print("平局!")#程序入口if__name__=="__main__":init()ifa==1:round3_1()round4_1()else:round3_0()round4_0()


游戏截图:

看完了这篇文章,相信你对用Python制作一个重力四子棋小游戏有了一定的了解,想了解更多相关知识,欢迎关注亿速云行业资讯频道,感谢各位的阅读!