### 171230 編程-井字棋（逆）的先手必勝策略

1625-5 王子昂 總結《2017年12月30日》 【連續第456天總結】
A. bambooctf-toddler-notakto-revenge
B.

========== Welcome to the Notakto Game ==========
Notakto is tic-tac-toe with both players playing the same piece ( an ‘X’ )
The player who end the game will LOSE THE GAME

0 | 1 | 2
—+—+—
3 | 4 | 5
—+—+—
6 | 7 | 8

========== 1 Round ==========

1 1 0
1 0 1
0 1 1

• 中心點有子
1 1 0
1 1 0
0 0 0
• 鄰角有子
1 0 1
0 0 0
1 0 1

x 0 x
0 0 0
0 1 0

1. 與該落子無鄰邊關系。

2. 避免形成4子封死的局面

from pwn import *
pairs = {0: (0, 8),1: (1, 7), 2:(2, 6), 3:(3, 5)}

def find(x):
for i in range(4):
if(x) in pairs[i]:
return i

def choose(x):
global flag
p = pairs[find(x)]
if(x)==p[0]:
p = p[1]
else:
p = p[0]
# 以對稱點為中心，選取4個點作為備選，遍歷它們，滿足在點棋盤上且對稱點未被下時可取
k = [p-1, p+1, p-3, p+3]
for i in k:
if((i//3==p//3 or i%3 == p%3)and i<=8 and i>=0 and i!=4 and flag[find(i)]==0):
return i

def iswin(s):
global flag
if(s.find("Round") != -1):
p = s.find("Round")
print(s[p-12:p+15])
flag = [0 for x in range(4)]

def recv(s):
p = s.find("My move:")
if(p==-1):
return -1

for i in s:
try:
if(i[0] == 'M'):
recv = int(i[9])
return recv
except:
pass
else:
return -1

r = remote("bamboofox.cs.nctu.edu.tw", 58793)
flag = [0 for i in range(4)]
while(1):
iswin(s)
k = s.find("My move")
if(k==-1):
r.sendline("4")
print("send:", 4)

else:
k = int(s[k+9])
print("recv:", k)
flag[int(find(k))] = 1
p = choose(k)
print('send:', p)
r.sendline(str(p))
flag[find(p)] = 1

try:
except:
print(r.recvall(timeout=3))
break

PS:

PPS:

C. 明日計划