Tic-Tac-Toe - VolgaCTF - 2016 - PPC
来源:互联网 发布:python hmac sha256 编辑:程序博客网 时间:2024/06/14 02:24
Tic-Tac-Toe An important step towards the strong AI is the ability of an artificial agent to solve a well-defined problem. A project by the name ‘tic-tac-toe’ was one of such test problems. It’s still up… nc tic-tac-toe.2016.volgactf.ru 45679
Tic-Tac-Toe就是小时候玩过的井字棋游戏。用nc连上去后(顺便说下,Windows下也可以下载一个nc,用起来挺方便的 Windows下的nc),服务器会和你玩游戏。它每次走一步后传回来一个棋盘,然后你输入一个编号(0~8,分别代表9个格子,表示你要在某个格子上走棋),这样就可以进行游戏了。每局胜利者获得1分,失败者不得分,平局则双方各得0.5分。进行500局后若我们得分多就能拿到Flag。
500局手动不现实,就要写AI实现。Tic-Tac-Toe的AI是比较容易写的。这样的AI可能不是最强,但击败服务器AI是绰绰有余了。最后得分是456:44大胜。
#coding=utf-8#敌方为-1,我方为1,无子为0#参数chess为棋盘数组,参数camp为1(我方)或-1(敌方)#可以使用PlayGame函数开始游戏~#游戏是否结束?返回值:-1,0,1,2,输,平,赢,未结束def CheckEnd(chess): for i in range(3): if chess[3*i]==chess[3*i+1]==chess[3*i+2] and chess[3*i]!=0: return chess[3*i] elif chess[i]==chess[3+i]==chess[6+i] and chess[i]!=0: return chess[i] if chess[0]==chess[4]==chess[8] and chess[0]!=0: return chess[0] elif chess[2]==chess[4]==chess[6] and chess[2]!=0: return chess[2] for i in range(9): if chess[i]==0: return 2 return 0#是否能直接胜利?如果可以,返回落子位置,否则返回-1def ToWin(chess,camp): for i in range(3): if chess[3*i]==0 and chess[3*i+1]+chess[3*i+2]==2*camp: return 3*i elif chess[3*i+1]==0 and chess[3*i]+chess[3*i+2]==2*camp: return 3*i+1 elif chess[3*i+2]==0 and chess[3*i]+chess[3*i+1]==2*camp: return 3*i+2 elif chess[i]==0 and chess[i+3]+chess[i+6]==2*camp: return i elif chess[i+3]==0 and chess[i]+chess[i+6]==2*camp: return i+3 elif chess[i+6]==0 and chess[i+3]+chess[i]==2*camp: return i+6 if chess[0]==0 and chess[4]+chess[8]==2*camp: return 0 elif chess[4]==0 and chess[0]+chess[8]==2*camp: return 4 elif chess[8]==0 and chess[0]+chess[4]==2*camp: return 8 elif chess[2]==0 and chess[4]+chess[6]==2*camp: return 2 elif chess[4]==0 and chess[2]+chess[6]==2*camp: return 4 elif chess[6]==0 and chess[2]+chess[4]==2*camp: return 6 else: return -1#处理特殊情况,如下图,X不能走角位置,否则会输# O _ _# _ X _# _ _ Odef ToSpecial(chess): if chess[1]==chess[3]==chess[5]==chess[7]==0 and chess[4]==1 and (chess[0]+chess[8]==-2 or chess[2]+chess[6]==-2): return 1 return -1#能否走成2-2连棋?如果可以,返回落子位置,否则返回-1def ToDouble(chess,camp): chess=chess[:] for i in range(9): if chess[i]==0: chess[i]=camp position=ToWin(chess,camp) if position!=-1: chess[position]=-camp if ToWin(chess,camp)!=-1: return i chess[position]=0 chess[i]=0 return -1#作出决定,返回值为落子位置,若无位置可下则返回-1def MakeChoice(chess): n=ToWin(chess,1) if n!=-1: return n n=ToWin(chess,-1) if n!=-1: return n n=ToSpecial(chess) if n!=-1: return n n=ToDouble(chess,1) if n!=-1: return n n=ToDouble(chess,-1) if n!=-1: return n to_choose=(4,0,2,6,8,1,3,5,7) #按中心>角>棱的优先级随便走 for i in to_choose: if chess[i]==0: return i return -1#输出棋盘def Output(chess): print('┏━┳━┳━┓') for i in range(3): out="┃" for j in range(3): if chess[3*i+j]==-1: out+='╳' elif chess[3*i+j]==0: out+=str(3*i+j)+' ' else: out+='●' out+='┃' print(out) if i<2: print('┣━╋━╋━┫') else: print('┗━┻━┻━┛')#开始游戏,我方即AI,敌方即玩家def PlayGame(): n=0 flag=0 while(1): n+=1 state=2 chess=[0,0,0,0,n%2,0,0,0,0] print("Let's have fun!") while(1): Output(chess) print('It\'s your turn. Please input a number between 0 and 8:') s=input() try: i=int(s) if i<0 or i>8 or chess[i]!=0: raise except: flag=1 break chess[i]=-1 state=CheckEnd(chess) if state==2: i=MakeChoice(chess) chess[i]=1 state=CheckEnd(chess) if state==1: print("You lose!") break elif state==0: print("Nobody win!") break elif state==-1: print("You win!") break if flag==1: break print()
这次顺便学习了一下Python的zio库的使用方法。有一个坑要注意一下,每局先动的可能是玩家也可能不是(是随机还是轮流我没注意),但总是先走的为’X’,后走的为’O’,所以还要写个代码确认一下自己是哪一方。
再吐槽一下主办方,最开始的时候要求的是60局,结果队友手动打到58局的时候断线了……为了防止手动他们又把要求改到2000局,按每局1~3秒计算要近1个小时才能搞定,很没意思。我个人觉得就100局,限定每局5秒内完成,总用时不超过5分钟即可。
#coding=utf-8#使用了AI里面的函数,在这里没有写出来,见上面from zio import *import re#通过字符串读入棋盘数组,role=1代表我方为'O',为-1代表我方为'X'def readChess(io,role): chess=[0,0,0,0,0,0,0,0,0] for i in range(3): s=io.readline() ss=s.split('|') for j in range(3): if ss[j].find('O')!=-1: chess[3*i+j]=role elif ss[j].find('X')!=-1: chess[3*i+j]=-role io.readline() return chess#第一次棋盘发回来的时候,如果是空的,那么我们是先手'X',否则我们是后手'O'def checkRole(chess): for i in range(9): if chess[i]!=0: return 1 return -1target=('95.213.237.91',45679)io=zio(target,print_read=False,print_write=False,timeout=9999999)io.readline()io.readline()io.writeline('fmyl') #Input your nameio.read_until('Round') #Round number 1.count=0while(1): count+=1 print(io.readline()) #Round number X io.readline() #当前比分啊啥的 flag=0 #flag检测现在是不是本局第一次下,如果是则要判断我们是哪一方 role=1 while(1): flag+=1 chess=readChess(io,role) if flag==1: role=checkRole(chess) if CheckEnd(chess)!=2: #CheckEnd是AI里面的函数,判断游戏状态(为2表示未结束) break m=MakeChoice(chess) #MakeChoice是AI里面的函数,根据当前棋况决定落子位置 chess[m]=1 io.writeline(str(m)) #下棋 if CheckEnd(chess)!=2: break if count==500: #500局之后不再游戏 breakprint(io.read_until(EOF)) #输出Flagio.interact()
- Tic-Tac-Toe - VolgaCTF - 2016 - PPC
- Tic-Tac-Toe
- [cf]Tic-tac-toe
- C - Tic-tac-toe
- Minimax-Tic Tac Toe
- Design Tic-Tac-Toe
- Design Tic-Tac-Toe
- Design Tic-Tac-Toe
- FZU Tic-Tac-Toe
- Tic-Tac-Toe FZU
- FZU2283-Tic-Tac-Toe
- tic-tac-toe游戏
- Analysis On Tic-Tac-Toe
- poj 3075 Tic-Tac-Toe
- checkio (tic-tac-toe)
- AOJ 0066 Tic Tac Toe
- UVa 10363 - Tic Tac Toe
- poj 2361 Tic Tac Toe
- 【HDU】5723 Abandoned country(2016 Multi-University)
- 第一篇微博,国际惯例
- 使用Spring的restTemplete进行Http请求
- Android Versions
- 盲打助手(Touch-Typing) 1.0 正式版 (下载)
- Tic-Tac-Toe - VolgaCTF - 2016 - PPC
- sql查询出来的一列多行数据拼接起来
- glMatrixMode()函数和glLoadldentity()说明
- [iOS] UIBezierPath画圆弧 addArcWithCenter
- StreamBenchmark工具,使用共享内存修改stream.c
- Android微信之简单文本分享(集成官方SDK-Android Studio)
- 通过usb方式ssh到越狱设备
- dubbox——windows,maven库先来一发
- Mac OS X RF与mysql-python冲突的问题