IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 五子棋 day7 -> 正文阅读

[游戏开发]五子棋 day7

写完忘记发了,今天补上

第九步
上一步我们已经完成了一个AI大脑的最核心功能。我们可以用它来对战了。

访问服务器http://xxx/join_game,会返回一个游戏编号game_id。之后你可以使用这个游戏编号,进行游戏http://xxx/play_game/{game_id}并查询游戏状态http://xxx/check_game/{game_id}

利用这三个功能我们就可以让我们的AI参战了。这个过程应该是这样的,这是一个典型的消息循环。

用join_game加入游戏

用check_game检查游戏状态

a. 如果游戏完成就退出

b. 如果不轮你下,就等一会,否则使用AI确定要落子的位置,并用play_game告知服务器你落子的位置

c. 返回到第2步用check_game检查游戏状态

其中join_game需要登录,需要提交用户名和密码,需要使用第五步使用的加密方法对密码加密,用户名写入user字段,加密后的密码写入password字段。另外需要传入字段data_type,将其设为json,返回字段game_id是加入的游戏编号。
play_game也需要登录,落子的坐标写入coord字段。
check_game不需要登录,返回当前的游戏状态, 会返回以下状态:

is_success,error 查询是否成功及错误原因
step 当前是第几步
creator 游戏一方的用户名
creator_name 游戏一方的名字(昵称)
creator_stone 游戏一方使用的棋子(x表示黑棋,o表示白棋)
opponent 游戏另一方的用户名
opponent_name 游戏另一方的名字(昵称)
opponent_stone 游戏另一方使用的棋子(x表示黑棋,o表示白棋)
ready 游戏是否就绪,两个玩家都在线时,游戏进入就绪状态
current_turn 当前应当落子的玩家的用户名
current_stone 当前应当落子的玩家的使用的棋子(x表示黑棋,o表示白棋)
left_time 剩余时间,为避免玩家过长思考,限制玩家必须在60秒内落子,否则游戏结束
winner 获胜的玩家的用户名,当游戏没有产生赢家时,该值为None
board 棋盘的坐标表示
last_step 上一步落子的坐标
win_step 如果一方获胜,这个字段给出连成五子的一条线的棋子坐标
注意不要过于频繁的检查游戏的状态,使用sleep函数等待服务器更新状态,两次检查以5到10秒的间隔为宜。

任务 9
实现消息循环,开始作战吧!
修改了第八步的代码,因为觉得每次对方落子后都模拟整个棋盘一次太慢,所以加了对方落子函数,下棋过程中就不再需要每次遍历board后重新绘制棋局了。轮到自己时利用last_step确认对方落子位置即可。

import time
import urllib
import urllib.request
import urllib.response
import json

win_type = {"CMMMM": 10000, "MCMMM": 10000, "MMCMM": 10000, "MMMCM": 10000, "MMMMC": 10000}  # 终-致胜
defense_type = {"OOOOC": 6000, "COOOO": 6000}  # 御-必守
latent_win_type = {".CMMM.": 5000, ".MCMM.": 5000, ".MMCM.": 5000, ".MMMC.": 5000}  # 创-两步致胜
latent_defense_type = {"COOO.": 2500, ".OOOC": 2500, ".OOCO.": 2500, ".OCOO.": 2500}  # 忍-两步防守
kill_type = {"OCMMM.": 2000, "OMCMM.": 2000, "OMMCM.": 2000, "OMMMC.": 2000, ".CMMMO": 2000, ".MCMMO": 2000,
             ".MMCMO": 2000, ".MMMCO": 2000}  # 攻-进攻
latent_kill_type = {".MMC.": 400, ".MCM.": 400, ".CMM.": 400}  # 蓄-两步进攻
foresee_type = {".OOC": 400, "COO.": 400, "MOOOC": 400, "COOOM": 400}  # 预-预防
invalid_type = {".MMCO": 200, ".MCMO": 200, ".CMMO": 200, "OMMC.": 200, "OMCM.": 200, "OCMM.": 200, "MOOC": 200,
                "COOM": 200}  # 缓-无效进攻
layout_type = {".MC.": 50, ".CM.": 50}  # 势-布局
com = [win_type, defense_type, latent_win_type, latent_defense_type, kill_type, latent_kill_type, foresee_type,
       invalid_type, layout_type]


def join_game():
    req = urllib.request.Request(f'http://xxx/join_game?user={user}&password={password}&data_type=json')
    res_data = urllib.request.urlopen(req)
    res = res_data.read()
    g_i = json.loads(res)['game_id']
    return g_i


def check_game():
    req = urllib.request.Request(f'http://xxx/check_game/{game_id}')
    res_data = urllib.request.urlopen(req)
    res = res_data.read()
    str1 = json.loads(res)
    return str1


def play_game(coord):
    print("我落子:" + coord)
    req = urllib.request.urlopen(
        f'http://xxx/play_game/{game_id}?user={user}&password={password}&coord={coord}')



def draw_board():  # 棋盘绘制
    for i in range(15):
        board.append([])
        for j in range(15):
            board[i].append(".")


def calculate_score(str1):  # 计算分数
    sum1 = 0
    for i in com:
        for item, value in i.items():
            if item in str1:
                sum1 = sum1 + value
    return int(sum1)


def game_transform(mes):  # 棋子转换
    if mes['current_stone'] == "x": # 该黑棋走
        for i in range(0, len(mes['board']), 2):
            a = ord(mes['board'][i]) - 97
            b = ord(mes['board'][i + 1]) - 97
            if board[a][b] == "x":
                board[a][b] = "M"
            elif board[a][b] == "o":
                board[a][b] = "O"
    else:
        for i in range(0, len(mes['board']), 2):
            a = ord(mes['board'][i]) - 97
            b = ord(mes['board'][i + 1]) - 97
            if board[a][b] == "x":
                board[a][b] = "O"
            elif board[a][b] == "o":
                board[a][b] = "M"


def transverse_judge(a, b):  # 横向判断
    a = a
    b = b
    str1 = []
    for j in range(-4, 5):
        if 0 <= b + j <= 14:
            str1.append(board[a][b + j])
        else:
            continue
    str1 = "".join(str1)
    return calculate_score(str1)


def portrait_judge(a, b):  # 纵向判断
    a = a
    b = b
    str1 = []
    for j in range(-4, 5):
        if 0 <= a + j <= 14:
            str1.append(board[a + j][b])
        else:
            continue
    str1 = "".join(str1)
    return calculate_score(str1)


def left_leaning_judge(a, b):  # 左倾判断(\)
    a = a
    b = b
    str1 = []
    for j in range(-4, 5):
        if 0 <= a + j <= 14 and 0 <= b + j <= 14:
            str1.append(board[a + j][b + j])
        else:
            continue
    str1 = "".join(str1)
    return calculate_score(str1)


def right_deviation_judge(a, b):  # 右倾判断(/)
    a = a
    b = b
    str1 = []
    for j in range(-4, 5):
        if 0 <= a - j <= 14 and 0 <= b + j <= 14:
            str1.append(board[a - j][b + j])
        else:
            continue
    str1 = "".join(str1)
    return calculate_score(str1)


def play(message):
    if message['current_turn'] != user:
        print("Waiting for the opponent...")
        return
    else:
        print("Let me think twice...")
        if message['board'] == '':
            play_game("hh")
            board[7][7] = message['current_stone']
        else:
            luozi(message)
            game_transform(message)
            sum_max = 0
            site1 = 0
            site2 = 0
            for num1 in range(15):
                for num2 in range(15):
                    max1 = 0
                    if board[num1][num2] == ".":
                        board[num1][num2] = "C"
                        max1 = max1 + transverse_judge(num1, num2) + portrait_judge(num1, num2) + left_leaning_judge(
                            num1, num2) + right_deviation_judge(num1, num2)
                        board[num1][num2] = "."
                    if sum_max < max1:
                        sum_max = max1
                        site1 = num1
                        site2 = num2
            str1 = chr(site1 + 97) + chr(site2 + 97)
            play_game(str1)
            board[site1][site2] = message['current_stone']


def luozi(mes):
    num1 = ord(mes['last_step'][0]) - 97
    num2 = ord(mes['last_step'][1]) - 97
    if mes['current_stone'] == "x":
        board[num1][num2] = "o"
    else:
        board[num1][num2] = "x"

user = "user"  #自己的用户名
password = "xxx"   #加密自己填
game_id = join_game()
board = []
draw_board()

while 1:
    mess = check_game()
    print(mess)
    if mess['winner'] != "None":
        print("胜利者:" + mess['winner'])
        break
    else:
        if mess['ready'] == "False":
            continue
        else:
            play(mess)
    time.sleep(6)

应该算只用了贪心的算法,后续优化可以选择学习极大极小算法AlphaBeta剪枝算法、多线程等等,也可以利用机器学习写ai进行训练。最后这个五子棋没有考虑黑棋禁手以及换手等规则,需要的话还得学。
总之这就能将就着用了,也挺简单就可以看明白的。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-09-04 17:52:40  更:2021-09-04 17:52:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/22 10:13:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码