Python 大作业之五子棋游戏(附代码)
Python-大作业之五子棋游戏(附代码)

Python 大作业——五子棋游戏姓名:学号:姓名:学号:一游戏介绍:我们设计的是五子棋游戏,支持两人一个鼠标对下,黑方用左键单击,白方用右键单击,谁先下均可,落子无悔,下过的棋子对方点击后不会变色,程序可自行判断输赢并在五子连珠时弹出结果对话框,游戏双方需遵守不在空地点击和一次下一子的规则。
二游戏代码设计:代码均为原创,没有借鉴和抄袭,首先是用户GUI界面设计,点击start进入游戏界面,点击quit则退出程序,为了方便判断和记录,我们按从左到右,从上到下的顺序给15x15=225颗棋子编号225,左键绑定函数callback1,点击后可算出它位于哪颗棋子上再画出来黑子,并把对应编号计入record这个列表,之后进入判断函数。
右键绑定函数callback2,点击后画出白子,对应编号计入recor这个列表,之后进入判断函数,其中总列表rec的作用是使棋子不被下第二遍。
三作业感想这个游戏虽然很小但是可以供室友们晚上娱乐之用,我们倾注了很多心血,之前采用模块化编程失败了很多次,有事件响应问题,参数传递问题,到第七个程序才成功,感谢张同珍老师指点了很多,我们学会了使用类,受益匪浅,对Python产生了浓厚的兴趣。
四过程截图五、实验代码from Tkinter import *from tkMessageBox import *class Game:def __init__(self):self.A=[]self.B=[]self.record=set()self.recor=set()self.rec=self.record|self.recorself.root=Tk()self.root.geometry("180x250")self.root.title("Wu Zi Qi Game")self.r=Canvas(self.root,width=180,height=210,bg="purple")pic=PhotoImage(file="beijing.gif")self.r.create_image(90,100,image=pic)self.r.place(x=0,y=15)Label(self.root,text="***Wu Zi Qi Game***",fg="red").place(x=20,y=0)Button(self.root,text="start",command=self.start).place(x=30,y=230)Button(self.root,text="quit ",command=self.root.destroy).place(x=100,y=230) self.r.mainloop()def start(self):self.root.destroy()self.top=Tk()self.top.title("Game Start")self.c=Canvas(self.top,width=480,height=480,bg="white")self.c.pack()self.c.create_rectangle(25,25,455,455,fill="gray")for i in range(30,451,30):for j in range(30,451,30):self.c.create_oval(i-2,j-2,i+2,j+2,fill="blue")for i in range(1,16):self.c.create_line(30,30*i,450,30*i)self.c.create_line(30*i,30,30*i,450)self.c.create_oval(234,234,246,246,fill="black")self.c.create_oval(115,115,125,125,fill="black")self.c.create_oval(355,115,365,125,fill="black")self.c.create_oval(115,355,125,365,fill="black")self.c.create_oval(355,355,365,365,fill="black")self.c.bind("<Button-1>",self.callback1)self.c.bind("<Button-3>",self.callback2)self.c.mainloop()def callback1(self,event):u,v=event.x,event.ys=u/15if s%2==1:self.x=(s+1)/2else:self.x=s/2l=v/15if l%2==1:self.y=(l+1)/2else:self.y=l/2g=(self.y-1)*15+self.xwhile g not in self.rec:self.c.create_oval(self.x*30-12,self.y*30-12,self.x*30+12,self.y*30+12,fill="black") self.A.append(g)self.record=set(self.A)self.rec=self.record|self.recorjudge=panduan(g,self.record)if judge==1:answer=showinfo("Game over","Black wins!")self.top.destroy()def callback2(self,event):u,v=event.x,event.ys=u/15if s%2==1:self.m=(s+1)/2else:self.m=s/2l=v/15if l%2==1:self.n=(l+1)/2else:self.n=l/2k=(self.n-1)*15+self.mwhile k not in self.rec:self.c.create_oval(self.m*30-12,self.n*30-12,self.m*30+12,self.n*30+12,fill="white") self.B.append(k)self.recor=set(self.B)self.rec=self.record|self.recorjudge=panduan(k,self.recor)if judge==1:answer=showinfo("Game over","White wins!")self.top.destroy()def panduan(g,record):#判断横排是否出现赢的情况if {g-4,g-3,g-2,g-1}<=record:return 1elif {g-3,g-2,g-1,g+1}<=record:return 1elif {g-2,g-1,g+1,g+2}<=record:return 1elif {g-1,g+1,g+2,g+3}<=record:return 1elif {g+1,g+2,g+3,g+4}<=record:return 1#判断竖列是否出现赢的情况elif {g-60,g-45,g-30,g-15}<=record:return 1elif {g-45,g-30,g-15,g+15}<=record:return 1elif {g-30,g-15,g+15,g+30}<=record:return 1elif {g-15,g+15,g+30,g+45}<=record: return 1elif {g+15,g+30,g+45,g+60}<=record: return 1#判断\列是否出现赢的情况elif {g-16,g-32,g-48,g-64}<=record:return 1elif {g-48,g-32,g-16,g+16}<=record:return 1elif {g-32,g-16,g+16,g+32}<=record:return 1elif {g-16,g+16,g+32,g+48}<=record: return 1elif {g+16,g+32,g+48,g+60}<=record: return 1#判断/列是否出现赢的情况elif {g-14,g-28,g-42,g-56}<=record:return 1elif {g-14,g-28,g-42,g+14}<=record:return 1elif {g-14,g-28,g+14,g+28}<=record:return 1elif {g-14,g+14,g+28,g+42}<=record:elif {g+14,g+28,g+42,g+56}<=record:return 1else:return 0def main():print "欢迎来到五子棋战场!黑方用左键,白方用右键,谁先下都可以,落子无悔,不要在棋盘周围空地点击。
五子棋代码

#include <stdio.h>#include"bios.h"#include <ctype.h>#include <conio.h>#include <dos.h>#define CROSSRU 0xbf /*右上角点*/#define CROSSLU 0xda /*左上角点*/#define CROSSLD 0xc0 /*左下角点*/#define CROSSRD 0xd9 /*右下角点*/#define CROSSL 0xc3 /*左边*/#define CROSSR 0xb4 /*右边*/#define CROSSU 0xc2 /*上边*/#define CROSSD 0xc1 /*下边*/#define CROSS 0xc5 /*十字交叉点*//*定义棋盘左上角点在屏幕上的位置*/#define MAPXOFT 5#define MAPYOFT 2/*定义1号玩家的操作键键码*/#define PLAY1UP 0x1157/*上移--'W'*/#define PLAY1DOWN 0x1f53/*下移--'S'*/#define PLAY1LEFT 0x1e41/*左移--'A'*/#define PLAY1RIGHT 0x2044/*右移--'D'*/#define PLAY1DO 0x3920/*落子--空格键*//*定义2号玩家的操作键键码*/#define PLAY2UP 0x4800/*上移--方向键up*/#define PLAY2DOWN 0x5000/*下移--方向键down*/ #define PLAY2LEFT 0x4b00/*左移--方向键left*/#define PLAY2RIGHT 0x4d00/*右移--方向键right*/ #define PLAY2DO 0x1c0d/*落子--回车键Enter*//*若想在游戏中途退出, 可按Esc 键*/#define ESCAPE 0x011b/*定义棋盘上交叉点的状态, 即该点有无棋子*//*若有棋子, 还应能指出是哪个玩家的棋子*/#define CHESSNULL 0 /*没有棋子*/#define CHESS1 'O'/*一号玩家的棋子*/#define CHESS2 'X'/*二号玩家的棋子*//*定义按键类别*/#define KEYEXIT 0/*退出键*/#define KEYFALLCHESS 1/*落子键*/#define KEYMOVECURSOR 2/*光标移动键*/#define KEYINVALID 3/*无效键*//*定义符号常量: 真, 假--- 真为1, 假为0 */#define TRUE 1#define FALSE 0/**********************************************************//* 定义数据结构*//*棋盘交叉点坐标的数据结构*/struct point{int x,y;};/**********************************************************//*自定义函数原型说明*/void Init(void);int GetKey(void);int CheckKey(int press);int ChangeOrder(void);int ChessGo(int Order,struct point Cursor);void DoError(void);void DoOK(void);void DoWin(int Order);void MoveCursor(int Order,int press);void DrawCross(int x,int y);void DrawMap(void);int JudgeWin(int Order,struct point Cursor);int JudgeWinLine(int Order,struct point Cursor,int direction); void ShowOrderMsg(int Order);void EndGame(void);/**********************************************************//**********************************************************//* 定义全局变量*/int gPlayOrder; /*指示当前行棋方*/struct point gCursor; /*光标在棋盘上的位置*/char gChessBoard[19][19];/*用于记录棋盘上各点的状态*/ /**********************************************************//**********************************************************//*主函数*/void main(){int press;int bOutWhile=FALSE;/*退出循环标志*/Init();/*初始化图象,数据*/while(1){press=GetKey();/*获取用户的按键值*/switch(CheckKey(press))/*判断按键类别*/{/*是退出键*/case KEYEXIT:clrscr();/*清屏*/bOutWhile = TRUE;break;/*是落子键*/case KEYFALLCHESS:if(ChessGo(gPlayOrder,gCursor)==FALSE)/*走棋*/ DoError();/*落子错误*/else{DoOK();/*落子正确*//*如果当前行棋方赢棋*/if(JudgeWin(gPlayOrder,gCursor)==TRUE){DoWin(gPlayOrder);bOutWhile = TRUE;/*退出循环标志置为真*/}/*否则*/else/*交换行棋方*/ChangeOrder();ShowOrderMsg(gPlayOrder);}break;/*是光标移动键*/case KEYMOVECURSOR:MoveCursor(gPlayOrder,press);break;/*是无效键*/case KEYINVALID:break;}if(bOutWhile==TRUE)break;}/*游戏结束*/EndGame();}/**********************************************************//*界面初始化,数据初始化*/void Init(void){int i,j;char *Msg[]={"Player1 key:"," UP----w"," DOWN--s"," LEFT--a"," RIGHT-d"," DO----space","","Player2 key:"," UP----up"," DOWN--down"," LEFT--left"," RIGHT-right"," DO----ENTER","","exit game:"," ESC",NULL,};/* 先手方为1号玩家*/gPlayOrder = CHESS1;/* 棋盘数据清零, 即棋盘上各点开始的时候都没有棋子*/ for(i=0;i<19;i++)for(j=0;j<19;j++)gChessBoard[i][j]=CHESSNULL;/*光标初始位置*/gCursor.x=gCursor.y=0;/*画棋盘*/textmode(C40);DrawMap();/*显示操作键说明*/i=0;textcolor(BROWN);while(Msg[i]!=NULL){gotoxy(25,3+i);cputs(Msg[i]);i++;}/*显示当前行棋方*/ShowOrderMsg(gPlayOrder);/*光标移至棋盘的左上角点处*/gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);}/*画棋盘*/void DrawMap(void){int i,j;clrscr();for(i=0;i<19;i++)for(j=0;j<19;j++)DrawCross(i,j);}/*画棋盘上的交叉点*/void DrawCross(int x,int y){gotoxy(x+MAPXOFT,y+MAPYOFT); /*交叉点上是一号玩家的棋子*/if(gChessBoard[x][y]==CHESS1) {textcolor(LIGHTBLUE);putch(CHESS1);return;}/*交叉点上是二号玩家的棋子*/if(gChessBoard[x][y]==CHESS2) {textcolor(LIGHTRED);putch(CHESS2);return;}textcolor(GREEN);/*左上角交叉点*/if(x==0&&y==0){putch(CROSSLU);return;}/*左下角交叉点*/if(x==0&&y==18){putch(CROSSLD);return;}/*右上角交叉点*/if(x==18&&y==0)putch(CROSSRU); return;}/*右下角交叉点*/if(x==18&&y==18) {putch(CROSSRD); return;}/*左边界交叉点*/if(x==0){putch(CROSSL); return;}/*右边界交叉点*/if(x==18){putch(CROSSR); return;}/*上边界交叉点*/if(y==0){putch(CROSSU); return;}/*下边界交叉点*/if(y==18){putch(CROSSD); return;}/*棋盘中间的交叉点*/ putch(CROSS);/*交换行棋方*/int ChangeOrder(void){if(gPlayOrder==CHESS1)gPlayOrder=CHESS2;elsegPlayOrder=CHESS1;return(gPlayOrder);}/*获取按键值*/int GetKey(void){char lowbyte;int press;while (bioskey(1) == 0);/*如果用户没有按键,空循环*/press=bioskey(0);lowbyte=press&0xff;press=press&0xff00 + toupper(lowbyte); return(press);}/*落子错误处理*/void DoError(void){sound(1200);delay(50);nosound();}/*赢棋处理*/void DoWin(int Order){sound(1500);delay(100);sound(0); delay(50);sound(800); delay(100);sound(0); delay(50);sound(1500);delay(100);sound(0); delay(50);sound(800); delay(100);sound(0); delay(50);nosound();textcolor(RED+BLINK);gotoxy(25,20);if(Order==CHESS1)cputs("PLAYER1 WIN!");elsecputs("PLAYER2 WIN!");gotoxy(25,21);cputs("\n");getch();}/*走棋*/int ChessGo(int Order,struct point Cursor){/*判断交叉点上有无棋子*/if(gChessBoard[Cursor.x][Cursor.y]==CHESSNULL) {/*若没有棋子, 则可以落子*/gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT); textcolor(LIGHTBLUE);putch(Order);gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT); gChessBoard[Cursor.x][Cursor.y]=Order;return TRUE;}elsereturn FALSE;}/*判断当前行棋方落子后是否赢棋*/int JudgeWin(int Order,struct point Cursor){int i;for(i=0;i<4;i++)/*判断在指定方向上是否有连续5个行棋方的棋子*/if(JudgeWinLine(Order,Cursor,i))return TRUE;return FALSE;}/*判断在指定方向上是否有连续5个行棋方的棋子*/int JudgeWinLine(int Order,struct point Cursor,int direction) {int i;struct point pos,dpos;const int testnum = 5;int count;switch(direction){case 0:/*在水平方向*/pos.x=Cursor.x-(testnum-1);pos.y=Cursor.y;dpos.x=1;dpos.y=0;break;case 1:/*在垂直方向*/pos.x=Cursor.x;pos.y=Cursor.y-(testnum-1);dpos.x=0;dpos.y=1;break;case 2:/*在左下至右上的斜方向*/pos.x=Cursor.x-(testnum-1);pos.y=Cursor.y+(testnum-1);dpos.x=1;dpos.y=-1;break;case 3:/*在左上至右下的斜方向*/pos.x=Cursor.x-(testnum-1);pos.y=Cursor.y-(testnum-1);dpos.x=1;dpos.y=1;break;}count=0;for(i=0;i<testnum*2+1;i++)/*????????i<testnum*2-1*/ {if(pos.x>=0&&pos.x<=18&&pos.y>=0&&pos.y<=18) {if(gChessBoard[pos.x][pos.y]==Order){count++;if(count>=testnum)return TRUE;}elsecount=0;}pos.x+=dpos.x;pos.y+=dpos.y;}return FALSE;}/*移动光标*/void MoveCursor(int Order,int press){switch(press){case PLAY1UP:if(Order==CHESS1&&gCursor.y>0)gCursor.y--;break;case PLAY1DOWN:if(Order==CHESS1&&gCursor.y<18)gCursor.y++;break;case PLAY1LEFT:if(Order==CHESS1&&gCursor.x>0)gCursor.x--;break;case PLAY1RIGHT:if(Order==CHESS1&&gCursor.x<18)gCursor.x++;break;case PLAY2UP:if(Order==CHESS2&&gCursor.y>0)gCursor.y--;break;case PLAY2DOWN:if(Order==CHESS2&&gCursor.y<18)gCursor.y++;break;case PLAY2LEFT:if(Order==CHESS2&&gCursor.x>0)gCursor.x--;break;case PLAY2RIGHT:if(Order==CHESS2&&gCursor.x<18)gCursor.x++;break;}gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); }/*游戏结束处理*/void EndGame(void){textmode(C80);}/*显示当前行棋方*/void ShowOrderMsg(int Order){gotoxy(6,MAPYOFT+20);textcolor(LIGHTRED);if(Order==CHESS1)cputs("Player1 go!");elsecputs("Player2 go!");gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); }/*落子正确处理*/void DoOK(void){sound(500);delay(70);sound(600);delay(50);sound(1000);delay(100);nosound();}/*检查用户的按键类别*/int CheckKey(int press){if(press==ESCAPE)return KEYEXIT;/*是退出键*/elseif( ( press==PLAY1DO && gPlayOrder==CHESS1) || ( press==PLAY2DO && gPlayOrder==CHESS2))return KEYFALLCHESS;/*是落子键*/elseif( press==PLAY1UP || press==PLAY1DOWN || press==PLAY1LEFT || press==PLAY1RIGHT || press==PLAY2UP || press==PLAY2DOWN || press==PLAY2LEFT || press==PLAY2RIGHT)return KEYMOVECURSOR;/*是光标移动键*/elsereturn KEYINVALID;/*按键无效*/}。
python单机五子棋的代码实现示例

python单机五⼦棋的代码实现⽰例五⼦棋相信⼤家都玩过,那么你们有没有试过⾃⼰动⼿编写过五⼦棋呢?今天来带着⼤家实现以下五⼦棋。
def initChessSquare(x,y): #初始化棋盘for i in range(15): # 每⼀⾏的交叉点坐标rowlist = []for j in range(15): # 每⼀列的交叉点坐标pointX = x+ j*40pointY = y+ i*40sp = StornPoint(pointX,pointY,0)rowlist.append(sp)initChessList.append(rowlist)创建初始化棋盘⽅法initChessSquare(x,y):根据棋盘图⽚的交叉点个数,遍历其所有交叉点坐标。
def eventHander(): #监听各种事件for event in pygame.event.get():global initRoleif event.type == QUIT:#事件类型为退出时pygame.quit()sys.exit()if event.type == MOUSEBUTTONDOWN: #当点击⿏标时x,y = pygame.mouse.get_pos() #获取点击⿏标的位置坐标i=0j=0for temp in initChessList:for point in temp:if x>=point.x-10 and x<=point.x+10 and y>=point.y-10 and y<=point.y+10:if point.value == 0 and initRole == 1: #当棋盘位置为空;棋⼦类型为⽩棋point.value = 1 #⿏标点击时,棋⼦为⽩棋judgeResult(i,j,1)initRole = 2 #切换⾓⾊elif point.value == 0 and initRole ==2: #当棋盘位置为空;棋⼦类型为⿊棋point.value = 2 #⿏标点击时,棋⼦为⿊棋judgeResult(i,j,2)initRole = 1 #切换⾓⾊breakj+=1i+=1j=0这⾥是检查事件。
python五子棋

python五⼦棋以后不更新了,把以前的⼀些东西发出来。
这是⼀个命令⾏环境的五⼦棋程序。
使⽤了minimax算法。
除了百度各个棋型的打分⽅式,所有代码皆为本⼈所撸。
本程序结构与之前的井字棋、⿊⽩棋⼀模⼀样。
有⼀点⼩问题,没时间弄了,就这样吧。
⼀、效果图(略)⼆、完整代码from functools import wrapsimport timeimport csv'''五⼦棋 Gobang作者:hhh5460时间:20181213'''#1.初始化棋盘#------------def init_board():'''初始化棋盘棋盘规格 15*15如下所⽰:board = [[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .],[. . . . . . . . . . . . . . .]]其中:. – 未被占⽤X – 被⿊棋占⽤O – 被⽩棋占⽤'''print('Init board...')time.sleep(0.5)n = 15board = [['.'for _ in range(n)] for _ in range(n)]return board#2.确定玩家,执⿊先⾛#--------------------def get_player():'''⼈类玩家选择棋⼦颜⾊(⿊'X'先⾛)'''humancolor = input("Enter your color. (ex. 'X' or 'O'):").upper()computercolor = ['X', 'O'][humancolor == 'X']return computercolor, humancolor#3.进⼊循环#----------#4.打印棋盘、提⽰⾛⼦#------------------------------def print_board(board): #ok'''打印棋盘、⽐分开局:1 2 3 4 5 6 7 8 9 a b c d e f1 . . . . . . . . . . . . . . .2 . . . . . . . . . . . . . . .3 . . . . . . . . . . . . . . .4 . . . . . . . . . . . . . . .5 . . . . . . . . . . . . . . .6 . . . . . . . . . . . . . . .7 . . . . . . . . . . . . . . .8 . . . . . . . . . . . . . . .9 . . . . . . . . . . . . . . .a . . . . . . . . . . . . . . .b . . . . . . . . . . . . . . .c . . . . . . . . . . . . . . .d . . . . . . . . . . . . . . .e . . . . . . . . . . . . . . .f . . . . . . . . . . . . . . .'''axises = list('123456789abcdef')print('', ''.join(axises))for i, v in enumerate(axises):print(v, ''.join(board[i]))#5.思考⾛法、放弃终⽌#--------------------def get_human_move(board, color): #ok'''取⼈类玩家⾛法'''giveup = True # 放弃标志legal_moves = _get_legal_moves(board, color)#print(','.join([translate_move(move) for move in legal_moves]), len(legal_moves))while True:_move = input("Enter your move.(ex.'cd' means row=c col=d): ").lower()move = translate_move(_move)if move in legal_moves:giveup = False # 不放弃breakreturn move, giveupdef _get_all_lianxin(board, move, color): #ok'''取当前点位落⼦后连星1.按照棋盘两连、三连、四连的个数 double triple quadra penta'''n = len(board)uncolor = ['X', 'O'][color == 'X'] # 反⾊lianxin = [] # 连星数,len(lianxin) == 4directions = ((0,1),(1,0),(1,1),(1,-1)) # 东, 南, 东南, 西南for direction in directions:dr, dc = direction # 步幅#r, c = move # 起点count = 1 # 连星数,算上起点(落⼦位置)jump_count = [0, 0] # 顺、反⽅向跳开⼀个空格之后的连星数jump_flag = [False, False] # 顺、反⽅向跳开⼀个空格的标志block = [False, False] # 顺、反⽅向是否堵死#name = ['','']for i,v in enumerate([1, -1]): # 顺、反⽅向分别⽤1、-1表⽰dr, dc = v*dr, v*dc # 步幅r, c = move[0]+dr, move[1]+dc # 先⾛⼀步while True:if not _is_on_board(board, [r, c]) or board[r][c] == uncolor: # 不在棋盘内,或对⽅棋⼦block[i] = True # 被堵死breakif board[r][c] == '.': # 为空if not _is_on_board(board, [r+dr, c+dc]) or board[r+dr][c+dc] != color: # 且下⼀格,不在棋盘内、或者⾮⼰⽅棋⼦breakif jump_flag[i] == True: # 前⾯已经跳了⼀格了,则终⽌break# 能⼒所限,不考虑⼜跳⼀格的情况!!!else:jump_flag[i] = Trueelif board[r][c] == color:if jump_flag[i] == True:jump_count[i] += 1else:count += 1r, c = r + dr, c + dc # 步进lianxin.append([count, jump_count, block])return lianxindef _move_score(board, move): #ok'''对该落⼦位置“打分”这个逻辑太复杂了,代码⼜长⼜臭!!暂时不考虑简化棋型分值:0.活五 +1000001.死五 +1000002.活四 +100003.死四 +10004.活三 +10005.死三 +1006.活⼆ +1007.死⼆ +108.活⼀ +109.死⼀ +2特别说明:10.跳N 两边棋型分相加 * 上⼀级分值的20% ?商榷lianxin == [[2,[0,0],[True,False]],[1,[0,0],[True,False]],[3,[1,0],[False,False]],[3,[2,1],[True,False]]]'''# 死⼀, 活⼀, 死⼆, 活⼆, 死三, 活三, 死四, 活四, 死五, 活五scores = [ 2, 10, 10, 100, 100, 1000, 1000, 10000,100000,100000]sum_score = 0for color in ['X','O']:for lianxin in _get_all_lianxin(board, move, color):count, jump_count, block = lianxinif jump_count[0] > 0 and jump_count[1] > 0: # 情况⼀:两边跳if block[0] == True and block[1] == True:if count + jump_count[0] + jump_count[1] + 2 < 5: continueelse:# 这边跳了if block[0] == True: # 有跳的,先把分数加了再说(查表加分)sum_score += scores[jump_count[0]*2-2] # 加死的分sum_score += min(scores[(jump_count[0]+count)*2-2] * 0.2, 200) # 上⼀级的20% else:sum_score += scores[jump_count[0]*2-1] # 加活的分sum_score += min(scores[(jump_count[0]+count)*2-1] * 0.2, 200) # 上⼀级的20% # 这边也跳了if block[1] == True: # 有跳的,先把分数加了再说(查表加分)sum_score += scores[jump_count[1]*2-2] # 加死的分sum_score += min(scores[(jump_count[1]+count)*2-2] * 0.2, 200) # 上⼀级的20% else:sum_score += scores[jump_count[1]*2-1] # 加活的分sum_score += min(scores[(jump_count[1]+count)*2-1] * 0.2, 200) # 上⼀级的20% # 中间sum_score += scores[count*2-1] # 中间加活的分elif jump_count[0] > 0 and jump_count[1] == 0: # 情况⼆:有⼀边跳if block[0] == True and block[1] == True:if count + jump_count[0] + jump_count[1] + 1 < 5: continueelse:# 跳的这边if block[0] == True: # 先把跳那边的分数加了再说(查表加分)sum_score += scores[jump_count[0]*2-2] # 加死的分sum_score += min(scores[(jump_count[0]+count)*2-2] * 0.2, 200) # 上⼀级的20% else:sum_score += scores[jump_count[0]*2-1] # 加活的分sum_score += min(scores[(jump_count[0]+count)*2-1] * 0.2, 200) # 上⼀级的20% # 没跳的那边if block[1] == True:sum_score += scores[count*2-2] # 加死的分else:sum_score += scores[count*2-1] # 加活的分elif jump_count[1] > 0 and jump_count[0] == 0: # 情况三:另⼀边跳if block[0] == True and block[1] == True:if count + jump_count[0] + jump_count[1] + 1 < 5: continueelse:# 跳的这边if block[1] == True: # 先把跳那边的分数加了再说(查表加分)sum_score += scores[jump_count[1]*2-2] # 加死的分sum_score += min(scores[(jump_count[1]+count)*2-2] * 0.2, 200) # 上⼀级的20% else:sum_score += scores[jump_count[1]*2-1] # 加活的分sum_score += min(scores[(jump_count[1]+count)*2-1] * 0.2, 200) # 上⼀级的20% # 没跳的那边if block[0] == True:sum_score += scores[count*2-2] # 加死的分else:sum_score += scores[count*2-1] # 加活的分elif jump_count[0] == 0 and jump_count[1] == 0: # 情况四:两边都没跳if block[0] and block[1]: # 两边都堵死了if count == 5: # 等于5才加,否则不加sum_score += scores[count*2-2] # -1,-2⼀样elif block[0] or block[1]: # 只堵死⼀边sum_score += scores[count*2-2] # 加死的分else:sum_score += scores[count*2-1] # 加活的分return sum_scoredef _get_center_enmpty_points(board): #ok'''取中⼼点附近的空位从中⼼点逐圈顺时针扫描,若连续两圈未有棋⼦,则停⽌'''n = len(board)center_point = [n//2, n//2] # 中⼼点[7,7],即'88'c1 = 0 # 空圈计数legal_moves = [] # 保存空位for i in range(8): #从内到外扫描8圈c2 = True # 空圈标志if i == 0:points = [[n//2, n//2]]else:# points = [第7-i⾏] + [第7+i列] + [第7+i⾏] + [第7-i列] # 从左上开始,顺时针⼀圈points = [[7-i,c] for c in range(7-i,7+i)] + \[[r,7+i] for r in range(7-i,7+i)] + \[[7+i,c] for c in range(7+i,7-i,-1)] + \[[r,7-i] for r in range(7+i,7-i,-1)]for point in points:if board[point[0]][point[1]] == '.': # 遇到空位,则legal_moves.append(point) # 保存点位else:c2 = False # 此圈⾮空if c2 == True: # 若此圈为空,空圈计数器加1c1 += 1if c1 == 2: breakelse: # 否则,清零c1 = 0return legal_moves # 越前,棋盘点位分值越⾼!def minimax(board, color, maximizingPlayer, depth):'''极⼤极⼩算法其中:maximizingPlayer = True #⼰⽅⽤例:_, move = minimax(board, 'X', True, 4) # 假设计算机执⿊'X'#参见: https:///wiki/Minimaxfunction minimax(node, depth, maximizingPlayer) isif depth = 0 or node is a terminal node thenreturn the heuristic value of nodeif maximizingPlayer thenvalue := −∞for each child of node dovalue := max(value, minimax(child, depth − 1, FALSE))return valueelse (* minimizing player *)value := +∞for each child of node dovalue := min(value, minimax(child, depth − 1, TRUE))return value(* Initial call *)minimax(origin, depth, TRUE)'''passdef get_computer_move(board, color):'''取计算机玩家⾛法计算机⾛⼦策略:1.对所有合法的落⼦位置逐个“打分”(如何“打分”,决定了计算机下棋的⽔平)2.取所有分值最⾼的落⼦位置'''print('Computer is thinking...', end='')legal_moves = _get_legal_moves(board, color)scores = [_move_score(board, move) for move in legal_moves]max_score = max(scores) # 最⾼分值best_move = legal_moves[scores.index(max_score)]print("'{}'".format(translate_move(best_move)))return best_movedef _is_legal_move(board, move): #ok'''判断落⼦位置是否合法说明:只要在棋盘内,且为空,即合法'''if _is_on_board(board, move) and board[move[0]][move[1]] == '.':return Truereturn Falsedef _get_legal_moves(board, color): #ok'''取当前颜⾊棋⼦所有的合法⾛法返回格式:[[x1,y1], [x2,y2], ...]'''legal_moves = _get_center_enmpty_points(board)return legal_movesdef _is_on_board(board, move): #ok'''判断点位是否在棋盘范围内'''n = len(board)return move[0] in range(n) and move[1] in range(n)def translate_move(move): #ok'''转换坐标如'1a'可转换为[0,9];⼜如[9,10]转换为'ab'此函数,只是为了⽅便,不是必要的'''axises = list('123456789abcdef')if type(move) is str: # 如'cd'row = axises.index(move[0])col = axises.index(move[1])_move = [row, col] # 得[2,3]elif type(move) is list: # 如[2,3]row = axises[move[0]]col = axises[move[1]]_move = '{}{}'.format(row, col) # 得'cd'return _move#6.落⼦#----------def do_move(board, move, color): #ok'''在当前位置落⼦'''assert board[move[0]][move[1]] == '.'board[move[0]][move[1]] = color#7.判断局⾯、是否终⽌#------------------------------def check_board(board, color): #ok'''检查棋盘返回:是否胜利'''n = len(board)directions = ((0,1),(1,0),(1,1),(1,-1)) # 东, 南, 东南, 西南# 四个搜索⽅向的起点(坐标),分四组。
五子棋游戏编程实现

五子棋游戏编程实现五子棋是一种古老而受欢迎的策略棋类游戏,它的规则简单而有趣。
在这篇文章中,我们将探讨五子棋游戏的编程实现,介绍游戏的规则,以及展示一种可行的代码实现。
一、游戏规则五子棋是一种双人对弈的棋类游戏,玩家轮流在棋盘上下棋。
棋盘是一个15×15的方格,每个方格可以放置一枚棋子。
玩家的目标是先在横向、纵向或斜线方向上连成五个自己的棋子,以获得胜利。
二、编程实现为了实现五子棋游戏,我们可以使用编程语言来模拟游戏过程。
以下是一种基于Python语言的简单实现示例:1. 创建棋盘首先,我们需要创建一个15×15的棋盘,可以使用一个二维数组来表示。
初始化时,所有的方格都为空。
2. 绘制游戏界面使用图形库来绘制游戏的界面,显示棋盘和棋子。
可以使用Python的turtle或者pygame库来实现。
3. 玩家下棋轮到玩家下棋时,可以通过鼠标点击棋盘上的方格来确定落子的位置。
根据玩家的选择,在对应的方格上绘制一个棋子。
4. 判断胜负在每一次玩家下棋后,我们需要判断游戏是否有人获胜。
通过检查横向、纵向和斜线方向上是否有连续的五个相同的棋子来判断胜负。
如果存在这样的连续序列,游戏结束,宣布获胜方。
5. 实现棋局复盘功能在游戏结束后,可以实现棋局的复盘功能,即回放整个游戏的过程。
通过记录每一步的下棋位置和落子顺序,可以在游戏结束后重新绘制棋局,供玩家观看。
三、总结通过上述步骤,我们可以实现一个简单的五子棋游戏。
当然,这只是一个基础的实现方式,你可以根据自己的需要和编程水平进行扩展和优化。
希望这篇文章能够帮助你了解如何用编程实现五子棋游戏,同时也能激发你对编程的兴趣。
编程是一项有趣且具有挑战性的技能,通过动手实践,你可以不断提升自己的编程能力。
加油!。
python实现五子棋小游戏

python实现五子棋小游戏本文实例为大家分享了python实现五子棋小游戏的具体代码,供大家参考,具体内容如下暑假学了十几天python,然后用pygame模块写了一个五子棋的小游戏,代码跟有缘人分享一下。
import numpy as npimport pygameimport sysimport tracebackimport copyfrom pygame.locals import *pygame.init()pygame.mixer.init()#颜色background=(201,202,187)checkerboard=(80,80,80)button=(52,53,44)#音乐play_chess_sound = pygame.mixer.Sound("music/play_chess.wav")play_chess_sound.set_volume(0.2)button_sound = pygame.mixer.Sound("music/button.wav")button_sound.set_volume(0.2)victor_sound = pygame.mixer.Sound("music/victory.wav")victor_sound.set_volume(0.2)#绘制棋盘def Draw_a_chessboard(screen):#填充背景色screen.fill(background)Background=pygame.image.load("background.jpg").convert_alpha()screen.blit(Background,(0,0))#画棋盘for i in range(21):pygame.draw.line(screen, checkerboard, (40*i+3, 3), (40*i+3, 803)) pygame.draw.line(screen, checkerboard, (3, 40*i+3), (803, 40*i+3))#画边线pygame.draw.line(screen, checkerboard, (3, 3), (803, 3),5)pygame.draw.line(screen, checkerboard, (3, 3), (3, 803),5)pygame.draw.line(screen, checkerboard, (803, 3), (803, 803),5)pygame.draw.line(screen, checkerboard, (3, 803), (803, 803),5)#画定位点pygame.draw.circle(screen, checkerboard, (163, 163), 6)pygame.draw.circle(screen, checkerboard, (163, 643), 6)pygame.draw.circle(screen, checkerboard, (643, 163), 6)pygame.draw.circle(screen, checkerboard, (643, 643), 6)pygame.draw.circle(screen, checkerboard, (403, 403), 6)#画‘悔棋'‘重新开始'跟‘退出'按钮pygame.draw.rect(screen,button,[900,350,120,100],5)pygame.draw.rect(screen,button,[900,500,200,100],5)pygame.draw.rect(screen,button,[900,650,200,100],5)s_font=pygame.font.Font('font.ttf',40)text1=s_font.render("悔棋",True,button)text2=s_font.render("重新开始",True,button)text3=s_font.render("退出游戏",True,button)screen.blit(text1,(920,370))screen.blit(text2,(920,520))screen.blit(text3,(920,670))#绘制棋子(横坐标,纵坐标,屏幕,棋子颜色(1代表黑,2代表白))def Draw_a_chessman(x,y,screen,color):if color==1:Black_chess=pygame.image.load("Black_chess.png").convert_alpha() screen.blit(Black_chess,(40*x+3-15,40*y+3-15))if color==2:White_chess=pygame.image.load("White_chess.png").convert_alpha() screen.blit(White_chess,(40*x+3-15,40*y+3-15))#绘制带有棋子的棋盘def Draw_a_chessboard_with_chessman(map,screen):screen.fill(background)Draw_a_chessboard(screen)for i in range(24):for j in range(24):Draw_a_chessman(i+1,j+1,screen,map[i][j])#定义存储棋盘的列表,#列表为24列24行是因为判断是否胜利函数里的索引会超出19#列表大一点不会对游戏有什么影响map=[]for i in range(24):map.append([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])#清零map列表def clear():global mapfor i in range(24):for j in range(24):map[i][j]=0#判断是否胜利def win(i, j):k = map[i][j]p=[]for a in range(20):p.append(0)for i3 in range(i-4,i+5):for j3 in range(j-4,j+5):if (map[i3][j3] == k and i3 - i == j3 - j and i3 <= i and j3 <= j):p[0]+=1if (map[i3][j3] == k and j3 == j and i3 <= i and j3 <= j):p[1]+=1if (map[i3][j3] == k and i3 == i and i3 <= i and j3 <= j):p[2]+=1if (map[i3][j3] == k and i3 - i == j3 - j and i3 >= i and j3 >= j):p[3]+=1if (map[i3][j3] == k and j3 == j and i3 >= i and j3 >= j):p[4]+=1if (map[i3][j3] == k and i3 == i and i3 >= i and j3 >= j):p[5]+=1if (map[i3][j3] == k and i - i3 == j3 - j and i3 <= i and j3 >= j):p[6]+=1if (map[i3][j3] == k and i3 - i == j - j3 and i3 >= i and j3 <= j):p[7]+=1if (map[i3][j3] == k and j - j3 == i - i3 and i3 <= i + 1 and i3 >= i - 3 and j3 <= j + 1 and j3 >= j - 3):p[8]+=1if (map[i3][j3] == k and j == j3 and i3 <= i + 1 and i3 >= i - 3 and j3 <= j + 1 and j3 >= j- 3):p[9]+=1if (map[i3][j3] == k and i == i3 and i3 <= i + 1 and i3 >= i - 3 and j3 <= j + 1 and j3 >= j - 3):p[10]+=1if (map[i3][j3] == k and j - j3 == i - i3 and i3 >= i - 1 and i3 <= i + 3 and j3 >= j - 1 and j3 <= j + 3):p[11]+=1if (map[i3][j3] == k and j == j3 and i3 >= i - 1 and i3 <= i + 3 and j3 >= j - 1 and j3 <= j + 3):p[12]+=1if (map[i3][j3] == k and i == i3 and i3 >= i - 1 and i3 <= i + 3 and j3 >= j - 1 and j3 <= j + 3):p[13]+=1if (map[i3][j3] == k and i - i3 == j3 - j and i3 <= i + 1 and i3 >= i - 3 and j3 >= j - 1 and j3 <= j + 3):p[14]+=1if (map[i3][j3] == k and i3 - i == j - j3 and i3 >= i - 1 and i3 <= i + 3 and j3 <= j + 1 and j3 >= j - 3):p[15]+=1if (map[i3][j3] == k and j - j3 == i - i3 and i3 <= i + 2 and i3 >= i - 2 and j3 <= j + 2 and j3 >= j - 2):p[16]+=1if (map[i3][j3] == k and j == j3 and i3 <= i + 2 and i3 >= i - 2 and j3 <= j + 2 and j3 >= j - 2):p[17]+=1if (map[i3][j3] == k and i == i3 and i3 <= i + 2 and i3 >= i - 2 and j3 <= j + 2 and j3 >= j - 2):p[18]+=1if (map[i3][j3] == k and i - i3 == j3 - j and i3 <= i + 2 and i3 >= i - 2 and j3 <= j + 2 and j3 >= j - 2):p[19]+=1for b in range(20):if p[b]==5:return Truereturn False#绘制提示器(类容,屏幕,字大小)def text(s,screen,x):#先把上一次的类容用一个矩形覆盖pygame.draw.rect(screen,background,[850,100,1200,100])#定义字体跟大小s_font=pygame.font.Font('font.ttf',x)#定义类容,是否抗锯齿,颜色s_text=s_font.render(s,True,button)#将字放在窗口指定位置screen.blit(s_text,(880,100))pygame.display.flip()#用于控制顺序t=True#用于结束游戏后阻止落子running=True#主函数def main():#将t,map,running设置为可改的global t,map,running,maps,r,h#将map置零clear()#定义储存所有棋盘状态的列表(用于悔棋)map2=copy.deepcopy(map)maps=[map2]#定义窗口screen = pygame.display.set_mode([1200,806])#定义窗口名字pygame.display.set_caption("五子棋")#在窗口画出棋盘,提示器以及按钮Draw_a_chessboard(screen)pygame.display.flip()clock=pygame.time.Clock()while True:#只有running为真才能落子,主要用于游戏结束后防止再次落子if running:if t:color=1text('黑棋落子',screen,54)else:color=2text('白棋落子',screen,54)for event in pygame.event.get():#点击x则关闭窗口if event.type ==pygame.QUIT:pygame.quit()sys.exit()#点击窗口里面类容则完成相应指令elif event.type == MOUSEBUTTONDOWN:if event.button == 1:x,y=event.pos[0],event.pos[1]for i in range(19):for j in range(19):#点击棋盘相应位置if i*40+3+20<x<i*40+3+60 and j*40+3+20<y<j*40+3+60 and not map[i][j] and running:#在棋盘相应位置落相应颜色棋子Draw_a_chessman(i+1,j+1,screen,color)#播放音效play_chess_sound.play(0)#在map里面记录落子位置map[i][j]=color#将map存入mapsmap3=copy.deepcopy(map)maps.append(map3)#判断落子后是否有五子一线if win(i,j):if t:text('黑棋胜利,请重新游戏',screen,30)else:text('白棋胜利,请重新游戏',screen,30)#播放音效victor_sound.play(0)#阻止再往棋盘落子running=Falsepygame.display.flip()t=not t#如果点击‘重新开始'if 900<x<1100 and 500<y<600:#取消阻止running=True#播放音效button_sound.play(0)#重新开始main()#点击‘退出游戏',退出游戏elif 900<x<1100 and 650<y<750:#播放音效button_sound.play(0)pygame.quit()sys.exit()#点击‘悔棋'elif 900<x<1020 and 350<y<450 and len(maps)!=1: #播放音效button_sound.play(0)#删除maps里最后一个元素del maps[len(maps)-1]#再将最后一个元素copy给mapmap=copy.deepcopy(maps[len(maps)-1])#切换顺序t=not t#将map显示出来Draw_a_chessboard_with_chessman(map,screen) #悔棋完成,阻止再次悔棋x,y=0,0clock.tick(60)if __name__ == "__main__":try:main()except SystemExit:passexcept:traceback.print_exc()pygame.quit()input()实现效果图如下:。
python实现网络五子棋

python实现⽹络五⼦棋本⽂实例为⼤家分享了python实现⽹络五⼦棋的具体代码,供⼤家参考,具体内容如下服务器端:import osimport socketimport threadingfrom tkinter import *from tkinter.messagebox import *def drawQiPan():for i in range(0, 15):cv.create_line(20, 20 + 40 * i, 580, 20 + 40 * i, width=2)for i in range(0, 15):cv.create_line(20 + 40 * i, 20, 20 + 40 * i, 580, width=2)cv.pack()# ⾛棋函数def callPos(event):global turnglobal MyTurnif MyTurn == -1: # 第⼀次确认⾃⼰的⾓⾊MyTurn = turnelse:if MyTurn != turn:showinfo(title="提⽰", message="还没轮到⾃⼰下棋")return# print("clicked at",event.x,event.y,true)x = event.x // 40y = event.y // 40print("clicked at", x, y, turn)if maps[x][y] != " ":showinfo(title="提⽰", message="已有棋⼦")else:img1 = images[turn]cv.create_image((x * 40 + 20, y * 40 + 20), image=img1)cv.pack()maps[x][y] = str(turn)pos = str(x) + "," + str(y)sendMessage("move|" + pos)print("服务器⾛的位置", pos)label1["text"] = "服务器⾛的位置" + pos# 输出输赢信息if win_lose():if turn == 0:showinfo(title="提⽰", message="⿊⽅你赢了")sendMessage("over|⿊⽅你赢了")else:showinfo(title="提⽰", message="⽩⽅你赢了")sendMessage("over|⽩⽅你赢了")# 换下⼀⽅⾛棋if turn == 0:turn = 1else:turn = 0# 发送消息def sendMessage(pos):global sglobal addrs.sendto(pos.encode(), addr)# 退出函数def callExit(event):pos = "exit|"sendMessage(pos)os.exit()# 画对⽅棋⼦def drawOtherChess(x, y):global turnimg1 = images[turn]cv.create_image((x * 40 + 20, y * 40 + 20), image=img1)maps[x][y] = str(turn)# 换下⼀⽅⾛棋if turn == 0:turn = 1else:turn = 0# 判断整个棋盘的输赢def win_lose():a = str(turn)print("a=", a)for i in range(0, 11):for j in range(0, 11):if maps[i][j] == a and maps[i + 1][j + 1] == a and maps[i + 2][j + 2] == a and maps[i + 3][j + 3] == a and \ maps[i + 4][j + 4] == a:print("x=y轴上形成五⼦连珠")return Truefor i in range(4, 15):for j in range(0, 11):if maps[i][j] == a and maps[i - 1][j + 1] == a and maps[i - 2][j + 2] == a and maps[i - 3][j + 3] == a and \ maps[i - 4][j + 4] == a:print("x=-y轴上形成五⼦连珠")return Truefor i in range(0, 15):for j in range(4, 15):if maps[i][j] == a and maps[i][j - 1] == a and maps[i][j - 2] == a and maps[i][j - 2] == a and maps[i][j - 4] == a:print("Y轴上形成了五⼦连珠")return Truefor i in range(0, 11):for j in range(0, 15):if maps[i][j] == a and maps[i + 1][j] == a and maps[i + 2][j] == a and maps[i + 3][j] == a and maps[i + 4][ j] == a:print("X轴形成五⼦连珠")return Truereturn False# 输出map地图def print_map():for j in range(0, 15):for i in range(0, 15):print(maps[i][j], end=' ')print('w')# 接受消息def receiveMessage():global swhile True: # 接受客户端发送的消息global addrdata, addr = s.recvfrom(1024)data = data.decode('utf-8')a = data.split("|")if not data:print('client has exited!')breakelif a[0] == 'join': # 连接服务器的请求print('client 连接服务器!')label1["text"] = 'client连接服务器成功,请你⾛棋!'elif a[0] == 'exit':print('client对⽅退出!')label1["text"] = 'client对⽅退出,游戏结束!'elif a[0] == 'over':print('对⽅赢信息!')label1["text"] = data.split("|")[0]showinfo(title="提⽰", message=data.split("1")[1])elif a[0] == 'move':print('received:', data, 'from', addr)p = a[1].split(",")x = int(p[0])y = int(p[1])print(p[0], p[1])label1["text"] = "客户端⾛的位置" + p[0] + p[1]drawOtherChess(x, y)s.close()def startNewThread(): # 启动新线程来接受客户端消息thread = threading.Thread(target=receiveMessage, args=())thread.setDaemon(True)if __name__ == '__main__':root = Tk()root.title("⽹络五⼦棋v2.0-服务器端")images = [PhotoImage(file='./images/BlackStone.png'), PhotoImage(file='./images/WhiteStone.png')] turn = 0MyTurn = -1maps = [[" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "] for y in range(15)]cv = Canvas(root, bg='green', width=610, height=610)drawQiPan()cv.bind("<Button-1>", callPos)cv.pack()label1 = Label(root, text="服务器端...")label1.pack()button1 = Button(root, text="退出游戏")button1.bind("<Button-1>", callExit)button1.pack()# 创建UDP SOCKETs = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)s.bind(('localhost', 8000))addr = ('localhost', 8000)startNewThread()root.mainloop()客户端:from tkinter import *from tkinter.messagebox import *import socketimport threadingimport os# 主程序root = Tk()root.title("⽹络五⼦棋v2.0--UDP客户端")imgs = [PhotoImage(file='./images/BlackStone.png'), PhotoImage(file='./images/WhiteStone.png')] turn = 0MyTurn = -1# 画对⽅棋⼦def drawOtherChess(x, y):global turnimg1 = imgs[turn]cv.create_image((x * 40 + 20, y * 40 + 20), image=img1)cv.pack()maps[x][y] = str(turn)# 换下⼀⽅⾛棋if turn == 0:turn = 1else:turn = 0# 发送消息def sendMessage(position):global ss.sendto(position.encode(), (host, port))# 退出函数def callExit(event):position = "exit|"sendMessage(position)os.exit()# ⾛棋函数def callback(event):global turnglobal MyTurnif MyTurn == -1:MyTurn = turnelse:if MyTurn != turn:showinfo(title="提⽰", message="还没轮到⾃⼰⾛棋")return# print("clicked at",event.x,event.y)x = event.x // 40y = event.y // 40print("clicked at", x, y, turn)if maps[x][y] != " ":showinfo(title="提⽰", message="已有棋⼦")else:img1 = imgs[turn]cv.create_image((x * 40 + 20, y * 40 + 20), image=img1)cv.pack()maps[x][y] = str(turn)position = str(x) + ',' + str(y)sendMessage("move|" + position)print("客户端⾛的位置", position)label1["text"] = "客户端⾛的位置" + position# 输出输赢信息if win_lose():if turn == 0:showinfo(title="提⽰", message="⿊⽅你赢了")sendMessage("over|⿊⽅你赢了!")else:showinfo(title="提⽰", message="⽩⽅你赢了!")sendMessage("over|⽩⽅你赢了!")# 换下⼀⽅⾛棋:if turn == 0:turn = 1else:turn = 0# 画棋盘def drawQiPan(): # 画棋盘for i in range(0, 15):cv.create_line(20, 20 + 40 * i, 580, 20 + 40 * i, width=2)for i in range(0, 15):cv.create_line(20 + 40 * i, 20, 20 + 40 * i, 580, width=2)cv.pack()# 输赢判断def win_lose():a = str(turn)print("a=", a)for i in range(0, 11):for j in range(0, 11):if maps[i][j] == a and maps[i + 1][j + 1] == a and maps[i + 2][j + 2] == a and maps[i + 3][j + 3] == a and \ maps[i + 4][j + 4] == a:print("x=y轴上形成五⼦连珠")return Truefor i in range(4, 15):for j in range(0, 11):if maps[i][j] == a and maps[i - 1][j + 1] == a and maps[i - 2][j + 2] == a and maps[i - 3][j + 3] == a and \ maps[i - 4][j + 4] == a:print("x=-y轴上形成五⼦连珠")return Truefor i in range(0, 15):for j in range(4, 15):if maps[i][j] == a and maps[i][j - 1] == a and maps[i][j - 2] == a and maps[i][j - 2] == a and maps[i][j - 4] == a:print("Y轴上形成了五⼦连珠")return Truefor i in range(0, 11):for j in range(0, 15):if maps[i][j] == a and maps[i + 1][j] == a and maps[i + 2][j] == a and maps[i + 3][j] == a and maps[i + 4][ j] == a:print("X轴形成五⼦连珠")return Truereturn False# 接受消息def receiveMessage(): # 接受消息global swhile True:data = s.recv(1024).decode('utf-8')a = data.split("|")if not data:print('server has exited!')breakelif a[0] == 'exit':print('对⽅退出!')label1["text"] = '对⽅退出!游戏结束!'elif a[0] == 'over':print('对⽅赢信息!')label1["text"] = data.split("|")[0]showinfo(title="提⽰", message=data.split("|")[1])elif a[0] == 'move':print('received:', data)p = a[1].split(",")x = int(p[0])y = int(p[1])print(p[0], p[1])label1["text"] = "服务器⾛的位置" + p[0] + p[1]drawOtherChess(x, y)s.close()# 启动线程接受客户端消息def startNewThread():thread = threading.Thread(target=receiveMessage, args=())thread.setDaemon(True)thread.start()if __name__ == '__main__':# 主程序maps = [[" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "] for y in range(15)]cv = Canvas(root, bg='green', width=610, height=610)drawQiPan()cv.bind("<Button-1>", callback)cv.pack()label1 = Label(root, text="客户端...")label1.pack()button1 = Button(root, text="退出游戏")button1.bind("<Button-1>", callExit)button1.pack()# 创建UDPs = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)port = 8000host = 'localhost'pos = 'join|'sendMessage(pos)startNewThread()root.mainloop()游戏执⾏页⾯:以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
python实现五子棋游戏(pygame版)

python实现五⼦棋游戏(pygame版)本⽂实例为⼤家分享了python五⼦棋游戏的具体代码,供⼤家参考,具体内容如下⽬录简介实现过程结语简介使⽤python实现pygame版的五⼦棋游戏;环境:Windows系统+python3.8.0游戏规则:1.分两位棋⼿对战,默认⿊棋先下;当在棋盘点击左键,即在该位置绘制⿊棋;2.⾃动切换到⽩棋,当在棋盘点击左键,即在该位置绘制⽩棋;3.轮流切换棋⼿下棋,当那⽅先形成5⼦连线者获胜(横、竖、斜、反斜四个⽅向都可以)。
游戏运⾏效果如下:实现过程1.新建⽂件settings.py,⽤来定义⼀些必须的基本属性和初始值;class Settings():def __init__(self):"""初始化的游戏配置"""# 屏幕宽⾼self.width = 700self.height = 554# ⽂字颜⾊和⼤⼩self.fontsize = 14self.fonttype = 'simsunnsimsun'# 棋盘格数self.number = 15# 棋盘左边距、上边距和间隔self.bd_left = 30self.bd_top = 30self.bd_space = 36# 判断游戏是否结束(默认开始)self.game_active = True# 判断哪⽅下棋(默认⿊⼦先写)self.chess_player = 1self.prompt_info = '当前棋⼿:⿊棋'# 开始校验输赢(两边合计9,因为已经有⼀边5步)self.win_number = 0# 设置背景图、⿊棋图⽚、⽩棋图⽚路径self.checkerboard_bg = 'images/checkerboard_bg.png'self.black_chess = 'images/black_chess.png'self.white_chess = 'images/white_chess.png'# 存储落⼦数据self.move_chess = []2.新建⽂件checkerboard.py,主要⽤来绘制背景图和棋格线;import sysimport pygameclass Checkerboard():def __init__(self, ck_settings, screen, position):self.ck_settings = ck_settingsself.screen = screenself.position = position# 颜⾊和坐标⼤⼩self.text_color = (0, 0, 0)self.font = pygame.font.SysFont(ck_settings.fonttype, ck_settings.fontsize)# 存储棋⼦坐标self.checkerboard = []# 加载背景图、⿊棋和⽩棋(当有图⽚不存在时,打印错误并退出游戏)try:self.bg_image = pygame.image.load(ck_settings.checkerboard_bg)self.black_image = pygame.image.load(ck_settings.black_chess).convert_alpha() # convert_alpha背景透明self.white_image = pygame.image.load(ck_settings.white_chess).convert_alpha()self.chess_rect = self.black_image.get_rect()except Exception as e:print('error:', e)sys.exit()def draw_board(self):# 存储棋⼦坐标for i in range(self.ck_settings.number):self.checkerboard.append([])for j in range(self.ck_settings.number):self.checkerboard[i].append(self.position(self.ck_settings.bd_left + i * self.ck_settings.bd_space, self.ck_settings.bd_top + j * self.ck_settings.bd_space)) # 绘制棋盘坐标for i in range(0, self.ck_settings.number):# ord返回字符的ASCII数值,chr再返回字符x_text = self.font.render(chr(ord('A') + i), True, self.text_color) # A-Oy_text = self.font.render(str(i + 1), True, self.text_color) # 1-15# 绘制xy轴坐标(在棋盘背景图绘制)self.bg_image.blit(x_text, (self.checkerboard[i][0].x - x_text.get_width() / 2, self.checkerboard[i][0].y - 20))self.bg_image.blit(y_text, (self.checkerboard[0][i].x - 20, self.checkerboard[0][i].y - y_text.get_height() / 2))# 绘制横竖线(在棋盘背景图绘制)pygame.draw.line(self.bg_image, self.text_color, self.checkerboard[0][i], self.checkerboard[self.ck_settings.number-1][i])pygame.draw.line(self.bg_image, self.text_color, self.checkerboard[i][0], self.checkerboard[i][self.ck_settings.number-1])# 绘制棋盘背景图self.screen.blit(self.bg_image, (0, 0))3.新建⽂件infopanel.py,主要⽤来绘制棋盘右边提⽰信息(暂时只有显⽰下棋⽅和获胜信息);import pygame.fontclass Infopanel():def __init__(self, ck_settings, screen):"""初始化属性"""self.settings = ck_settingsself.screen = screenself.screen_rect = screen.get_rect()# 设置⽂字颜⾊和字体⼤⼩_color = (217, 8, 10)self.font = pygame.font.SysFont(ck_settings.fonttype, 16)def draw_info(self, info):"""将⽂字渲染为图像,并定位到右边⽔平居中"""_image = self.font.render(info, True, _color)_image_rect = _image.get_rect()_image_rect.right = self.screen_rect.right - (self.screen_rect.width - 536 - _image_rect.width) / 2_image_rect.top = 50# 绘制到屏幕self.screen.blit(_image, _image_rect)4.新建⽂件“game_functions.py”,存放跟游戏有关的所有业务逻辑函数;import sysimport pygame# 棋def update_board(ck_settings, cb, index_coordinates, position):"""更新棋盘信息"""# 判断棋⼿(⿊棋或⽩棋)if ck_settings.chess_player == 1:ck_settings.prompt_info = '当前棋⼿:⽩棋'img = cb.black_imagechess_type = 'black'else:ck_settings.prompt_info = '当前棋⼿:⿊棋'img = cb.white_imagechess_type = 'white'"""落棋"""dropState = check_at(ck_settings, index_coordinates)if dropState:i, j = index_coordinateschess_x = cb.checkerboard[j][i].x - cb.chess_rect.width / 2chess_y = cb.checkerboard[j][i].y - cb.chess_rect.height / 2# 累计步数(两边合计)ck_settings.win_number += 1# 落⼦并转换棋⼿ck_settings.move_chess.append({'type': chess_type, 'coord': position(i, j)}) cb.bg_image.blit(img, (chess_x, chess_y))ck_settings.chess_player *= -1# 合计9步开始校验输赢if ck_settings.win_number >= 9:check_stats(ck_settings, (i, j))else:ck_settings.prompt_info = '已经有其他棋⼦'# 检查(i,j)位置是否已占⽤def check_at(ck_settings, index_coordinates):for item in ck_settings.move_chess:if index_coordinates == item['coord']:return Falsereturn Truedef check_stats(ck_settings, pos):"""校验四个⽅向,是否有了输赢"""pos_i, pos_j = posdirects = [(1, 0), (0, 1), (1, 1), (1, -1)] # 横、竖、斜、反斜四个⽅向检查for direct in directs:line_checkerboard = []d_x, d_y = directlast = ck_settings.move_chess[-1]line_ball = [] # 存放在⼀条线上的棋⼦for ball in ck_settings.move_chess:# 跟最后落⼦判断if ball['type'] == last['type']:x = ball['coord'].x - last['coord'].xy = ball['coord'].y - last['coord'].yif d_x == 0:if x == 0:line_ball.append(ball['coord'])if d_y == 0:if y == 0:line_ball.append(ball['coord'])if x * d_y == y * d_x:line_ball.append(ball['coord'])if len(line_ball) >= 5: # 只有5⼦及以上才继续判断sorted_line = sorted(line_ball)for i, item in enumerate(sorted_line):index = i + 4if index < len(sorted_line):if d_x == 0:y1 = item.yy2 = sorted_line[index].y# 此点和第5个点⽐较y值,如相差为4则连成5⼦if abs(y1 - y2) == 4:ck_settings.prompt_info = '⿊棋获胜' if last['type'] == 'black' else '⽩棋获胜' else:x1 = item.xx2 = sorted_line[index].x# 此点和第5个点⽐较x值,如相差为4则连成5⼦if abs(x1 - x2) == 4:ck_settings.prompt_info = '⿊棋获胜' if last['type'] == 'black' else '⽩棋获胜' else:break# 事件def check_events(ck_settings, cb, position):"""监听事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type == pygame.MOUSEBUTTONDOWN:# 点击左键if event.button == 1:pos = pygame.mouse.get_pos() # 获取点击实际坐标# 判断是否溢出x_first = cb.checkerboard[0][0].xx_last = cb.checkerboard[ck_settings.number - 1][ck_settings.number - 1].xy_first = cb.checkerboard[0][0].yy_last = cb.checkerboard[ck_settings.number - 1][ck_settings.number - 1].yif pos[0] < x_first or pos[0] > x_last or pos[1] < y_first or pos[1] > y_last:ck_settings.prompt_info = '落⼦位置不正确!'else:index_coordinates = to_index(ck_settings, pos)update_board(ck_settings, cb, index_coordinates, position)def to_index(ck_settings, pos):"""实际坐标转换为棋盘下标"""i = round((pos[1] - ck_settings.bd_top) / ck_settings.bd_space)j = round((pos[0] - ck_settings.bd_left) / ck_settings.bd_space)return (i, j)5.新建⽂件gobang.py,主函数⽤来初始化程序,并同步更新程序的信息;import pygamefrom settings import Settingsfrom checkerboard import Checkerboardfrom collections import namedtupleimport game_functions as gffrom infopanel import Infopaneldef run_game():"""运⾏游戏"""# 初始化游戏屏幕pygame.init()# 创建时钟对象 (可以控制游戏循环频率)clock = pygame.time.Clock()# 配置实例化ck_settings = Settings()screen = pygame.display.set_mode((ck_settings.width, ck_settings.height))pygame.display.set_caption('五⼦棋游戏')# namedtuple创建类似于元组的数据类型,除了可以⽤索引访问,能够迭代,还能⽤属性名访问数据position = namedtuple('Position', ['x', 'y'])# 创建实例cb = Checkerboard(ck_settings, screen, position)# 实例化⾯板信息infopanel = Infopanel(ck_settings, screen)while ck_settings.game_active:# 绘制棋盘cb.draw_board()# 绘制⾯板信息infopanel.draw_info(ck_settings.prompt_info)# 检查玩家事件并更新棋盘gf.check_events(ck_settings, cb, position)# 让最近绘制的屏幕可见pygame.display.flip()# 通过时钟对象指定循环频率clock.tick(60) # 每秒循环60次run_game()6.在⽂件gobang.py⽬录路径下,执⾏命令“python gobang.py”弹出窗⼝,即可对其操作游玩。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Python 大作业——五子棋游戏姓名:吴欣学号:姓名:张雨清学号:一游戏介绍:我们设计的是五子棋游戏,支持两人一个鼠标对下,黑方用左键单击,白方用右键单击,谁先下均可,落子无悔,下过的棋子对方点击后不会变色,程序可自行判断输赢并在五子连珠时弹出结果对话框,游戏双方需遵守不在空地点击和一次下一子的规则。
二游戏代码设计:代码均为原创,没有借鉴和抄袭,首先是用户GUI界面设计,点击start进入游戏界面,点击quit则退出程序,为了方便判断和记录,我们按从左到右,从上到下的顺序给15x15=225颗棋子编号225,左键绑定函数callback1,点击后可算出它位于哪颗棋子上再画出来黑子,并把对应编号计入record这个列表,之后进入判断函数。
右键绑定函数 callback2,点击后画出白子,对应编号计入recor这个列表,之后进入判断函数,其中总列表rec的作用是使棋子不被下第二遍。
三作业感想这个游戏虽然很小但是可以供室友们晚上娱乐之用,我们倾注了很多心血,之前采用模块化编程失败了很多次,有事件响应问题,参数传递问题,到第七个程序才成功,感谢张同珍老师指点了很多,我们学会了使用类,受益匪浅,对Python产生了浓厚的兴趣。
四过程截图五、实验代码from Tkinter import *from tkMessageBox import *class Game:def __init__(self):self.A=[]self.B=[]self.record=set()self.recor=set()self.rec=self.record|self.recorself.root=Tk()self.root.geometry("180x250")self.root.title("Wu Zi Qi Game")self.r=Canvas(self.root,width=180,height=210,bg="purple")pic=PhotoImage(file="beijing.gif")self.r.create_image(90,100,image=pic)self.r.place(x=0,y=15)Label(self.root,text="***Wu Zi Qi Game***",fg="red").place(x=20,y=0) Button(self.root,text="start",command=self.start).place(x=30,y=230) Button(self.root,text="quit",command=self.root.destroy).place(x=100,y=230)self.r.mainloop()def start(self):self.root.destroy()self.top=Tk()self.top.title("Game Start")self.c=Canvas(self.top,width=480,height=480,bg="white")self.c.pack()self.c.create_rectangle(25,25,455,455,fill="gray")for i in range(30,451,30):for j in range(30,451,30):self.c.create_oval(i-2,j-2,i+2,j+2,fill="blue")for i in range(1,16):self.c.create_line(30,30*i,450,30*i)self.c.create_line(30*i,30,30*i,450)self.c.create_oval(234,234,246,246,fill="black")self.c.create_oval(115,115,125,125,fill="black")self.c.create_oval(355,115,365,125,fill="black")self.c.create_oval(115,355,125,365,fill="black")self.c.create_oval(355,355,365,365,fill="black")self.c.bind("<Button-1>",self.callback1)self.c.bind("<Button-3>",self.callback2)self.c.mainloop()def callback1(self,event):u,v=event.x,event.ys=u/15if s%2==1:self.x=(s+1)/2else:self.x=s/2l=v/15if l%2==1:self.y=(l+1)/2else:self.y=l/2g=(self.y-1)*15+self.xwhile g not in self.rec:self.c.create_oval(self.x*30-12,self.y*30-12,self.x*30+12,self.y*30+12,fill="bl ack")self.A.append(g)self.record=set(self.A)self.rec=self.record|self.recorjudge=panduan(g,self.record)if judge==1:answer=showinfo("Game over","Black wins!")self.top.destroy()def callback2(self,event):u,v=event.x,event.ys=u/15if s%2==1:self.m=(s+1)/2else:self.m=s/2l=v/15if l%2==1:self.n=(l+1)/2else:self.n=l/2k=(self.n-1)*15+self.mwhile k not in self.rec:self.c.create_oval(self.m*30-12,self.n*30-12,self.m*30+12,self.n*30+12,fill="wh ite")self.B.append(k)self.recor=set(self.B)self.rec=self.record|self.recorjudge=panduan(k,self.recor)if judge==1:answer=showinfo("Game over","White wins!") self.top.destroy()def panduan(g,record):#判断横排是否出现赢的情况if {g-4,g-3,g-2,g-1}<=record:return 1elif {g-3,g-2,g-1,g+1}<=record:return 1elif {g-2,g-1,g+1,g+2}<=record:return 1elif {g-1,g+1,g+2,g+3}<=record:return 1elif {g+1,g+2,g+3,g+4}<=record:return 1#判断竖列是否出现赢的情况elif {g-60,g-45,g-30,g-15}<=record:return 1elif {g-45,g-30,g-15,g+15}<=record:return 1elif {g-30,g-15,g+15,g+30}<=record:return 1elif {g-15,g+15,g+30,g+45}<=record:return 1elif {g+15,g+30,g+45,g+60}<=record:return 1#判断\列是否出现赢的情况elif {g-16,g-32,g-48,g-64}<=record:return 1elif {g-48,g-32,g-16,g+16}<=record:return 1elif {g-32,g-16,g+16,g+32}<=record:return 1elif {g-16,g+16,g+32,g+48}<=record:return 1elif {g+16,g+32,g+48,g+60}<=record:return 1#判断/列是否出现赢的情况elif {g-14,g-28,g-42,g-56}<=record:return 1elif {g-14,g-28,g-42,g+14}<=record:return 1elif {g-14,g-28,g+14,g+28}<=record:return 1elif {g-14,g+14,g+28,g+42}<=record:return 1elif {g+14,g+28,g+42,g+56}<=record:return 1else:return 0def main():print "欢迎来到五子棋战场!黑方用左键,白方用右键,谁先下都可以,落子无悔,不要在棋盘周围空地点击。
Are you ready?"game=Game()main()(注:文档可能无法思考全面,请浏览后下载,供参考。
可复制、编制,期待你的好评与关注)。