导航
·运用Python——爬虫_网易云音乐热评
·运用Python——游戏_四子棋_劳拉下棋
文章目录
- 导航
- 1.游戏规则
- 2.玩法分析
- 3.部分详解
- 第一部分:初始化
- 第二部分:棋盘显示
- 第三部分:玩家输入
- 第四部分:运行
- 第五部分:胜利判断
- 4.完整代码
- 5.游戏截图
- 完
新手学习Python,写第一个Python小游戏——四连环(重力四子棋)
1.游戏规则
棋盘为8*6
玩家输入列号与电脑下四子棋,棋会随着重力下降
胜利方式是一行/一列/左右斜线连四颗棋子
2.玩法分析
拆分成了这几个部分,用自定义函数封装,便于修改:
·初始化
·棋盘显示
·玩家输入
·游戏运行
·判断胜利
引用库:random
3.部分详解
第一部分:初始化
def init():global board #棋盘,二维列表global rest_num #每一列剩余棋子数,一维整型列表global a #先手判定,整型global reminded_line #未被填满列的记录,一维整型列表global symbol0 #执棋方记录1,字典global symbol1 #执棋方记录2,字典symbol1 = {"O": "玩家","X": "电脑"}symbol0 = {"X": "玩家","O": "电脑"}a = random.randint(0,2)reminded_line = [0,1,2,3,4,5,6,7]board = [["-"] * 8 for i in range(6)]rest_num = [6 for i in range(8)]show(board)
这里初始化定义了一些之后用得到的变量
第二部分:棋盘显示
def show(board):for i in range(6):for j in range(8):print(board[i][j],end=" ")print()
用索引下标的方式遍历棋盘并打印
第三部分:玩家输入
def playerInput(rest_num):while True:inp = int(input()) - 1 #注意:列表起始于list[0]if inp in range(0,8): #符合8列if rest_num[inp] > 0: #该列有空余return inpelse:print("输入错误")else:print("输入错误")
输入用While True循环,直到输入正确
要判定输入的列号是否在1-8列内,且该列有空余!
第四部分:运行
先后手问题在主函数内用 if 判断初始化内全局变量a来执行不同顺序
四子棋的前三个回合不会分出胜负,因此拆分成前三个回合和剩余回合
这里可以算多此一举吧,前三次只是少了判断胜负
用 round3_0、round4_0 和 round3_1、round4_1 区分
游戏运行使用for次数循环,胜利提前结束即可
def round3_0():round_cout = 0 #回合计数for i in range(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)def round3_1(): #同上,只是先后手顺序改变round_cout = 0for i in range(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)def round4_0():round_cout = 3 #回合计数for i in range(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#如果该列已满,则在剩余列编号列表中移除,排除随机到该列if rest_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] -= 1if rest_num[robot_line] == 0:reminded_line.remove(robot_line)show(board)IsWinning(board, "X", symbol0)print("平局!") #最后分不出胜负就是平局def round4_1():round_cout = 3for i in range(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] -= 1if rest_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] -= 1if rest_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)、执棋方记录
def IsWinning(board,chess_type,symbol):rowIsWinning(board,chess_type,symbol)leftSlashIsWinning(board,chess_type,symbol)board_s = []for i in board:board_s.append(i[::-1]) #左右对称leftSlashIsWinning(board_s, chess_type, symbol)
========
直线判定:
def rowIsWinning(board,chess_type,symbol):#竖4for line_no in range(8):for height_no in range(3):if board[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)#横4for height_no in range(6):for line_no in range(5):if board[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循环表示
def leftSlashIsWinning(board,chess_type,symbol):#表示左上绿色部分for init_height in range(3):for init_line in range(init_height + 1):if board[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)#表示右下绿色部分for init_height in range(3,6):for init_line in range(init_height+2,8):if board[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)#中间特殊情况for init_height in range(3):init_line = init_height +1if board[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)
4.完整代码
import randomdef init():global boardglobal rest_numglobal aglobal reminded_lineglobal symbol0global symbol1symbol1 = {"O": "玩家","X": "电脑"}symbol0 = {"X": "玩家","O": "电脑"}a = random.randint(0,2)reminded_line = [0,1,2,3,4,5,6,7]board = [["-"] * 8 for i in range(6)]rest_num = [6 for i in range(8)]show(board)def show(board):for i in range(6):for j in range(8):print(board[i][j],end=" ")print()def IsWinning(board,chess_type,symbol):rowIsWinning(board,chess_type,symbol)leftSlashIsWinning(board,chess_type,symbol)board_s = []for i in board:board_s.append(i[::-1])leftSlashIsWinning(board_s, chess_type, symbol)def rowIsWinning(board,chess_type,symbol):for line_no in range(8):for height_no in range(3):if board[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)for height_no in range(6):for line_no in range(5):if board[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)def leftSlashIsWinning(board,chess_type,symbol):for init_height in range(3):for init_line in range(init_height + 1):if board[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)for init_height in range(3,6):for init_line in range(init_height+2,8):if board[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)for init_height in range(3):init_line = init_height +1if board[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)def playerInput(rest_num):while True:inp = int(input()) - 1if inp in range(0,8):if rest_num[inp] > 0:return inpelse:print("输入错误")else:print("输入错误")def round3_0():round_cout = 0for i in range(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)def round3_1():round_cout = 0for i in range(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)def round4_0():round_cout = 3for i in range(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] -= 1if rest_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] -= 1if rest_num[robot_line] == 0:reminded_line.remove(robot_line)show(board)IsWinning(board, "X", symbol0)print("平局!")def round4_1():round_cout = 3for i in range(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] -= 1if rest_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] -= 1if rest_num[robot_line] == 0:reminded_line.remove(robot_line)show(board)IsWinning(board, "X", symbol1)print("平局!")#程序入口
if __name__ == "__main__":init()if a == 1:round3_1()round4_1()else:round3_0()round4_0()
5.游戏截图
完
如果有更好的方法欢迎在评论区交流
感谢浏览