AI五子棋_09 无线循环对局

前言

五子棋算法几乎没有改进
将周围9个点变为15个点。黑棋的时候可以走棋局中心。
循环一百次开局。可以无人看管自动对局100把。
错误绕过机制。由于平局 超时 服务器机器人出错导致的问题全部绕过。

棋局结果写入文件。

import requests as re
import time as t
import json

def fastModular(x):
	"""x[0] = base """
	"""x[1] = power"""
	"""x[2] = modulus"""
	result = 1
	while(x[1] > 0):
		if(x[1] & 1):
			result = result * x[0] % x[2]
		x[1] = int(x[1]/2)
		x[0] = x[0] * x[0] % x[2]
	return result

def str_to_num(strings):
	sum = 0
	lens = len(strings)
	for i in range(0,lens):
		sum += ord(strings[i])*256**(lens-i-1)
	return sum

def encodeLogin(password):
         # 公钥
        power = 65537
        modulus = 135261828916791946705313569652794581721330948863485438876915508683244111694485850733278569559191167660149469895899348939039437830613284874764820878002628686548956779897196112828969255650312573935871059275664474562666268163936821302832645284397530568872432109324825205567091066297960733513602409443790146687029

        return hex(fastModular([str_to_num(password),power,modulus]))

def join_game(user, myHexPass):
        """加入游戏并返回一个 get回复包对象"""

        url = 'http://2**.2**.**.1**:9012/join_game/'
        param = {
                'user' : user,
                'password': myHexPass,
                'data_type':'json'
                }

        getHtml = re.get(url, params = param)

        print(f"Open a new game{getHtml.text}")
        return getHtml

def check_game(game_id):
        url = 'http://2**.2**.**.1**:9012/check_game/'+ str(game_id)
        getState = re.get(url)
        #print(getState.text)    # 测试显示数据用
        return getState
        
def getIndexNum(coords):
        """coords y x"""
        # 0行 [0]='.'--- [14]='.'[15]='\n'
        # 1行 [16]='.'--- [30]='.'[31]='\n'
        # 2行 [32]='.'--- [46]='.'[47]='\n'
        # 15行 [240]='.'--- [257]='.'[255]='\n'
        return (ord(coords[0]) - ord('a'))*16 + ord(coords[1]) - ord('a')

def allIndexStr():
        spot = []
        for i in range(0,15):
                for j in range(0,16):
                        spot.append(chr(i+97) + chr(j+97))
        return spot

def getLine(coord,board):
        """
        获得中心点的四周点情况 返回一个字符串列表
        coord[0] y 纵坐标 coord[1] x 控制横坐标
        board  棋局
        """
        line = ['', '' , '' , '']
        i =0
        """ 核心思想就是 将周围点两个坐标x,y的限制 转化为一个位置index的限制 """
        while(i != 15):
                if ord(coord[1])-ord('a')- 7 + i in range(0, 15) :      # line[0]是横线 只需保证 横坐标在棋盘里就好
                        line[0] +=board[(ord(coord[0])-ord('a'))*16 + ord(coord[1])-ord('a')- 7 + i]
                else:
                        line[0] += ' '
                if ord(coord[0])-ord('a') -7 + i in range(0, 15) :      # line[2]是竖线 只需保证 纵坐标在棋盘里就好
                        line[2] +=board[(ord(coord[0])-ord('a')- 7 + i)*16 + ord(coord[1])-ord('a')]
                else:
                        line[2] += ' '
                # - 7 + i 是从最小值上升判断  + 7 - i 是从最大值下降判断 两者没有什么不同 根据index的求法而定
                if ord(coord[1])-ord('a')- 7 + i in range(0, 15) and ord(coord[0])-ord('a') - 7 + i in range(0, 15) :    # line[1]是\线 保证 横纵坐标都在棋盘里就好
                        line[1] +=board[(ord(coord[0])-ord('a')- 7 + i)*16 + ord(coord[1])-ord('a')- 7 + i]
                else:
                        line[1] += ' '
                if ord(coord[1])-ord('a') + 7 - i in range(0, 15) and ord(coord[0])-ord('a') - 7 + i in range(0, 15) :   # line[3]是/线 保证 横纵坐标都在棋盘里就好
                        line[3] +=board[(ord(coord[0])-ord('a')- 7 + i)*16 + ord(coord[1])-ord('a')+ 7 - i]
                else:
                        line[3] += ' '
                        
                i += 1
        return line

def judge(testOrder, bw = '.'):
        if (len(testOrder)//2) % 2 == 0 or bw == 'x':     # 我是黑方
                return 'MO'
        else:                           # 我是白方
                return 'OM'
def RuleWithPoints():
        RWP = {
                ("CMMMM","MCMMM","MMCMM","MMMCM","MMMMC") : 10000,
                ("COOOO","OCOO","OOCOO","OOCOO","OOOOC") : 6000,
                (".CMMM.",".MCMM.",".MMCM.",".MMMC.") : 5000,
                ("COOO.",".OOOC",".OOCO.",".OCOO.") :2500,
                ("OCMMM.","OMCMM.","OMMCM.","OMMMC.",".CMMMO",".MCMMO",".MMCMO",".MMMCO"):2000,
                (".MMC.",".MCM.",".CMM.") : 400,
                (".OOC","COO.","MOOOC","COOOM") : 1000,
                (".MMCO",".MCMO",".CMMO","OMMC.","OMCM.","OCMM.","MOOC","COOM") : 200,
                (".MC.",".CM.") : 200,
                ('.') :1,
                }
        return RWP

def Board(Order, bw = '.'):
        board = ''              # 棋板
        for i in range(0,15):
                board += '...............' + '\n'
                
        step = 0 # 步数 用于判断黑白 黑方先走
        BW = judge(Order,bw)
        
        for i in range(0, len(Order), 2): # i = 0 2 4 6 8 

                index = getIndexNum(Order[i:i+2])

                # Python不允许直接修改字符串 只能用拼接的方法
                if (step % 2) == 0:
                        board = board[0: index] + BW[0] + board[index + 1:]
                else:
                        board = board[0: index] + BW[1] + board[index + 1:]
                step += 1
        return board

def getMaxCoords(Order,RWP, indexSrc):
        """对于每一个当下的棋局 返回一个最成功的下点"""

        board = Board(Order) 

        maxCoord = ''
        maxPoints = 0
        for i in range(0,len(board)):
                if board[i] == '.':
                        tempBoard = board[0: i] + 'C' + board[i + 1:]
                        coord = indexSrc[i]
                        lines4 = ','.join(getLine(coord,tempBoard))
                        points = 0
                        for rules,value in RWP.items():
                                for rul in range(0, len(rules)) :
                                        if rules[rul] in lines4:
                                                points += value * lines4.count(rules[rul])
                
                        if points > maxPoints :
                                maxPoints = points
                                maxCoord = coord
                                
        print(f"{maxCoord} {maxPoints}",end=' ')
        return maxCoord

def play_game(user, myHexPass, game_id, coord ):
        url = 'http://2**.2**.**.1**:9012/play_game/' + str(game_id)
        param = {
                'user' : user,
                'password': myHexPass,
                'data_type':'json',
                'coord' : coord
                }
        re.get(url, params=param)
        
user = 'xxxx'
password = 'xxxxx'
myHexPass = encodeLogin(password)
RWP = RuleWithPoints()
indexSrc = allIndexStr()

games = 0
winTimes = 0 

while games < 100:
        game_id = join_game(user, myHexPass ).json()["game_id"]
        state = check_game(game_id).json()
        
        print("Looking for game partners ...")
        while state['ready'] == "False":
                state = check_game(game_id).json()
                print(state['ready'],end=" ")
                t.sleep(5)

        if state['creator'] != user:
                opponent = state['creator']
                myStone = state['opponent_stone']
        else:
                opponent = state['opponent_name']
                myStone = state['creator_stone']
                
        while state['ready'] == "True":
                if state['current_turn'] == user :
                        order = state['board']
                        coord = getMaxCoords(order, RWP, indexSrc)
                        play = play_game(user, myHexPass, game_id, coord)
                        print(f"Playing {coord}")
                else:
                        print(f"Waiting for {opponent} to play")
                t.sleep(5)

                # 遇到某些服务器机器人可能会报错 增加程序韧性
                try:
                        stateTemp = check_game(game_id)
                        state = stateTemp.json()
                except:
                        print("Error! Your opponent is broken! We're about to open new game ")
                        with open('errorHt_' + str(games) + '.html','w') as file:
                                file.write(stateTemp)
                        with open('gameList.txt','a',encoding = 'utf-8') as f:
                                f.write(f"{games}\t Your opponent {opponent} at step {state['step']} is causing a server error!" + '\n')
                        t.sleep(60)
                        break
                try:
                    if int(state['left_time']) < 5 or state['step'] == '254' or state['step'] == '255':
                        print(f'Your opponent {opponent} maybe timeout or gameEqual')
                        break
                except KeyError:
                    break
                       
                
                if state['winner'] != "None":
                        
                        print(f"The winner is {state['winner']}")
                        board  = Board(state['board'], myStone)
                        if state['winner'] == user:
                                winTimes += 1
                        with open('./gameList.txt','a',encoding = 'utf-8') as f:
                                f.write(f"{games}\t Paly with {opponent}.\t The winner is {state['winner']}" + '\n')
                                f.write(board)
                        break
        games  += 1

posted @   Dba_sys  阅读(115)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示