Python实现黑白棋人机对弈

简书:Python实现黑白棋人机对弈https://www.jianshu.com/p/37191dffbe07

  • 规则
    黑白棋的每颗棋子由黑白两色组成,一面白,一面黑。每次落子,把本方颜色的棋子放在棋盘的空格上,若在横、竖、斜八个方向的任一方向上有本方棋子,则被夹在中间的对手棋子全部翻转为本方棋子颜色;并且,仅在可以翻转棋子的地方才能落子。如果一方至少有一步合法棋步可下,他就必须落子,不得弃权。棋盘已满或双方都没有棋子可下时棋局结束,以棋子数目来计算胜负,棋子多的一方获胜。在棋盘还没有下满时,如果一方的棋子已经被对方吃光,则棋局也结束,将对手棋子吃光的一方获胜。
    两位玩家轮流下棋,直到一方没有符合规则的落子位置,在这种情况下,剩下的一方继续下棋,直到对手有了可以落子的位置。此时,恢复两者轮流下棋的顺序。如果一方落子在非法位置,则视为放弃本次对弈,对方获胜。游戏结束的条件:1)整个棋盘满了;2)一方的棋子已经被对方吃光;3)两名玩家都没有可以落子的棋盘格;4)一方落子在非法位置。前3 种情况以棋子数目来计算胜负,棋子多的一方获胜;第4 种情况判定对方获胜。

  • 计算机选择落子位置的策略
    选择落子位置的策略 选择落子位置的策略对每个可能 的落子 位置,计算 该位置的 该位置的 “分值 ”(可以翻转的对手棋子数量 可以翻转的对手棋子数量 可以翻转的对手棋子数量.同分数选择行数小的。

  • 实现思路
    黑白棋玩家的子的坐标放在集合中,改变集合元素实现下棋。根据集合中元素打印棋盘。

  • 亟待完善的地方
    机器下棋策略可以改善,设计递推方法
    不同的持棋方式写了重复的代码,可以进一步包装
    无效代码可以删除,如cont,
    命名

import timeimport csvclass HeiBaiPlayer(object):status = True  # 是否有位置可以下defeat = False  # 是否赢了R_LIST = [(i, j) for i in range(-1, 2) for j in range(-1, 2)]R_LIST.remove((0, 0))count = 0def __init__(self, dim, players, _color):  # _color只能是hei or bai ,players只能是com or peopself.hei = {(dim//2+1, dim//2), (dim//2, dim//2+1)}self.players = playersself.bai = {(dim//2, dim//2), (dim//2+1, dim//2+1)}self.dim = dimself._color = _color  # dicdef qp_print(self):'''根据场中的hei和bai打印棋盘:return:'''for i in range(self.dim + 1):if i == 0:print(" ", end='')print(''.join([str(chr(97 + x)) for x in range(self.dim)]))else:for j in range(self.dim + 1):if j == 0:print(chr(96 + i), end='')else:if (i, j) in self.hei:print('X', end='')elif (i, j) in self.bai:print('O', end='')else:# print((i,j))print('.', end='')print()def legal_position(self,players):''':param players:bai或者hei的集合:return: 字典 {bai玩家或者hei玩家可以落子位置:反转对手子的位置}'''if players == self.hei:_players = self.baielse:_players = self.heikong = [(i, j) for i in range(1, self.dim + 1) for j in range(1, self.dim + 1)]kong = set(kong) - self.hei - self.bai# print(kong)p_players_list_in = {}  # 如果落在p,会有的夹在中间的反色子集合for p in kong:all_r_players_list_in = []  # 所有方向的反色夹在中间子的集合for r in self.R_LIST:_players_list_in = []  # 某一方向夹在中间反色子的集合i = 1lst = []while 1:if (p[0] + i * r[0], p[1] + i * r[1]) in _players:lst.append(tuple([p[0] + i * r[0], p[1] + i * r[1]]))i += 1if (p[0] + i * r[0], p[1] + i * r[1]) in players:_players_list_in += lstbreakif i > self.dim + 1:breakelse:breakif _players_list_in:  # 如果这个方向有jiazai中间的反色子all_r_players_list_in += _players_list_inif all_r_players_list_in:  # 如果落在p,会夹在中间的反色子集合【】p_players_list_in[p] = all_r_players_list_in# print(p_players_list_in,'这是测试')return p_players_list_indef callback(self):'''根据对象不同选择不同的下棋方式:return: 机器下棋还是人工下棋'''if self.players == 'com':return self.computer_xiaif self.players == 'peop':return self.players_xiadef color(self):if self._color == 'hei':return self.heireturn self.baidef hefa(self,players, p):'''测试某一位置是否合法,如果合法,返回相应反转的子的位置,不合法返回False:param p: 位置元组:return:列表'''if p in self.legal_position(players).keys():return self.legal_position(players)[p]return Falsedef defen(self, players, p):'''某一位置的得分:param players:set:param p:(,):return:'''return len(self.hefa(players, p))def computer_xia(self,players):  # 要么是黑,要么是白,players类型是集合if not self.legal_position(players).keys():print('com no Invalid move\n========')self.status = Falseelse:self.status = Truep_score = {}for p in self.legal_position(players).keys():p_score[p] = self.defen(players, p)score = max(p_score.values())for p in [(i, j) for i in range(1, self.dim + 1) for j in range(1, self.dim + 1)]:if self.hefa(players, p):if p_score[p] == score:return {p: self.legal_position(players)[p]}def players_xia(self, players):  # 要么是黑,要么是白,players类型是集合'''人工下棋,先判断有无位置可以下,在让用户选择落子位置,如果位置出错 self.defeat = True:param players: 人player拥有子位置的集合:return: {落子位置:反转对面位置}'''if not self.legal_position(players).keys():print('poeple no Invalid move\n========')self.status = Falseelse:self.status = Truetry:s = input("你的落子位置(例如ab:a行b列):?")posintion = tuple([ord(s[0]) - 96, ord(s[1]) - 96])if posintion in self.legal_position(players).keys():return {posintion:self.legal_position(players=players)[posintion]}else:self.defeat = Trueexcept Exception as e:print('Sth Wrong, Try again',e)s = input("你的落子位置:?")posintion = tuple([ord(s[0]) - 96, ord(s[1]) - 96])if posintion in self.legal_position(players).keys():return {posintion: self.legal_position(players=players)[posintion]}else:self.defeat = Truedef change(self, dic):'''下棋之后改变hei和bai中的元素:param dic: {落子位置:反转对面位置}:return: 新的hei和bai集合'''if self._color == 'hei':self.hei = self.hei | set(list(dic.keys())) | set(list(dic.values())[0])self.bai = self.bai - set(list(dic.values())[0])else:self.bai = self.bai | set(list(dic.keys())) | set(list(dic.values())[0])self.hei = self.hei - set(list(dic.values())[0])def com_turn():'''电脑下棋:return:'''com.bai = peop.baicom.hei = peop.heicolor_set = com.color()  # 颜色集合HeiBaiPlayer_function = com.callback()  # 下棋方法传入集合dic = HeiBaiPlayer_function(color_set)  # 得到下棋位置和反转位置if not com.status:peop.qp_print()else:if peop.status == False:peop.status = Truecom.count = 0print('==' * 5)print('机器下棋位置:反转对方位置', dic)com.change(dic)# print(com.hei, com.bai)com.qp_print()if not peop.status:peop.status = Truedef peop_turn():'''人下棋:return:'''peop.bai = com.baipeop.hei = com.heicolor_set = peop.color()HeiBaiPlayer_function = peop.callback()  # 下棋的函数dic = HeiBaiPlayer_function(color_set)if not peop.status:peop.qp_print()elif not peop.defeat:if com.status == False:com.status = Truepeop.count = 0print('=='*5)# print('人的下棋位置:反转对方位置', dic)peop.change(dic)# print('黑,白', peop.hei, peop.bai)peop.qp_print()else:peop.qp_print()peop.defeat = True# print("人输了")t1 = time.time()begin_time = time.strftime('%Y%m%d %H:%M:%S')Dimension = eval(input('Dimension:'))  # 用户输入开始OX = input('Computer plays (X/O):')if OX == 'O':com = HeiBaiPlayer(dim=Dimension, players='com', _color='bai')peop = HeiBaiPlayer(dim=Dimension, players='peop', _color='hei')hei_player = 'computer'if OX == 'X':com = HeiBaiPlayer(dim=Dimension, players='com', _color='hei')peop = HeiBaiPlayer(dim=Dimension, players='peop', _color='bai')hei_player = 'players'if com._color == 'hei':count = 0peop.qp_print()while 1:com_turn()if peop.status == False and com.status == False:print("Both players have no valid move.")print("Game Over")print('com:{}**peop:{}'.format(com.color(), peop.color()))if len(com.color()) > len(peop.color()):print('com win!!')elif len(com.color()) < len(peop.color()):print('players win!!')else:print('0比0')score = str(len(com.color())) +':'+ str(len(peop.color()))breakpeop_turn()if peop.defeat:print('Invalid move.\nGame over.')print('com win')score = 'Human give up'breakif peop.status == False and com.status == False:print("Both players have no valid move.")print("Game Over")print('com:{}**peop:{}'.format(com.color(), peop.color()))if len(com.color()) > len(peop.color()):print('com win!!')elif len(com.color()) < len(peop.color()):print('players win!!')else:print('0比0')score = str(len(com.color())) +':'+ str(len(peop.color()))breakpeop.qp_print()if peop._color == 'hei':count = 0peop.qp_print()while 1:peop_turn()if peop.defeat:print('Invalid move.\nGame over.')print('com win')score = 'Human give up'breakif peop.status == False and com.status == False:print("Both players have no valid move.")print("Game Over")print('com:{}**peop:{}'.format(com.color(), peop.color()))if len(com.color()) > len(peop.color()):print('com win!!')elif len(com.color()) < len(peop.color()):print('players win!!')else:print('0比0')score = str(len(peop.color())) +':'+ str(len(com.color()))breakcom_turn()if peop.status == False and com.status == False:print("Both players have no valid move.")print("Game Over")print('com:{}**peop:{}'.format(com.color(), peop.color()))if len(com.color()) > len(peop.color()):print('com win!!')elif len(com.color()) < len(peop.color()):print('players win!!')else:print('0比0')score = str(len(peop.color())) +':'+ str(len(com.color()))breakpeop.qp_print()t2 = time.time()time_sep = int(t2 - t1)if hei_player == 'computer':bai_player = 'players'else:bai_player = 'computer'def save_info(begin_time, time_sep, dim, hei_player, bai_player, score):with open('reversi.csv', 'a', newline='') as f:writer = csv.writer(f)writer.writerow([begin_time, time_sep, str(dim)+'*'+str(dim), hei_player, bai_player, score])save_info(begin_time, time_sep, Dimension, hei_player, bai_player, score)


[1]: https://www.jianshu.com/p/37191dffbe07

Python实现黑白棋人机对弈相关推荐

  1. 黑白棋python代码框架_Python实现黑白棋人机对弈

    Python实现黑白棋人机对弈 规则 黑白棋的每颗棋子由黑白两色组成,一面白,一面黑.每次落子,把本方颜色的棋子放在棋盘的空格上,若在横.竖.斜八个方向的任一方向上有本方棋子,则被夹在中间的对手棋子全 ...

  2. python大作业黑白棋记分_Python实现黑白棋人机对弈

    Python实现黑白棋人机对弈 规则 黑白棋的每颗棋子由黑白两色组成,一面白,一面黑.每次落子,把本方颜色的棋子放在棋盘的空格上,若在横.竖.斜八个方向的任一方向上有本方棋子,则被夹在中间的对手棋子全 ...

  3. Python 实现黑白棋

    Python实现黑白棋 题目要求 电脑的策略 游戏结束的条件 解题思路 关键逻辑 关键函数 Init_board: printBoard: computer_move: human_move: che ...

  4. python+pyGame 黑白棋游戏

    注:以下程序为根据相应的字符界面程序改编而来,写的不好,若有好的建议,望留言告知.而若能帮助一二访客,幸甚! 继续学习python. 为了学习起来更有趣,继续以游戏的方式来学习. 注:前几天学习了In ...

  5. JAVA黑白棋之算法浅析

     引言   本为主要对我在开发JAVA黑白棋人机算法过程中所用的博弈思想.估值函数.搜索算法分3个方面进行了阐述,由于本人水平有限,如果大家希望了解更多有关黑白棋博弈策略以及人机算法的深入的理论研究, ...

  6. Windows游戏设计(三)- 黑白棋游戏 - 使用Win32 SDK

    注:以下程序为本人原创,写的不好,若有好的建议,望留言告知.而若能帮助一二访客,幸甚! 上回用Python 写黑白棋,后来想添加个最小最大规则搜索博弈树的算法,没能实现,于是想先用Win32 写一个, ...

  7. [Python] 黑白棋(翻转棋)小游戏

    [Python] 黑白棋(翻转棋)小游戏 游戏介绍 黑白棋(Reversi or Othello)在西方和日本很流行.游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负. 规则 黑白棋的每颗 ...

  8. python五子棋双人对弈_PyQt5实现五子棋游戏(人机对弈)

    这篇博客主要是为了学习Python和PyQt,因为对棋类游戏比较热衷,所以从规则较简单的五子棋入手,利用PyQt5实现图形界面,做一个可以进行人机对弈的脚本,最后打包成应用程序.AI的算法打算用神经网 ...

  9. 基于Python的Reversi黑白棋游戏设计与开发

    摘 要 黑白棋是一个相当易学,而且很受欢迎的游戏.近年来,随着机器性能的提高和相关理论的完善,人工智能这一领域变得越来越重要,在实际生活中的运用也越来越广泛.为了学习简单的人工智能,我决定用Pytho ...

最新文章

  1. 课堂上我们为什么不发言
  2. 修改ubuntu的终端提示符
  3. python实训计算总秒数,Python:如何获取每个吉利秒数
  4. FreeMarker学习
  5. oracle查询pga大小GB,Oracle如何调整SGA和PGA的大小
  6. 远程办公招聘_招聘远程人才时要寻找的5种技能
  7. linux网络编程之广播详细代码及文档说明 -,Linux网络编程之广播
  8. R语言基础入门(4)之数据类型与相应运算2
  9. bzoj1293 [SCOI2009]生日礼物 单调队列
  10. MySQL Merge存储引擎
  11. IIS建立两个站点服务,只有一个公网IP
  12. [机器学习]推荐系统之协同过滤算法
  13. Julia: 通过简单实践理解机器学习概念(flux.jl)
  14. AndroidManifest中android:label与第三方库冲突问题
  15. 解决SecureCRT信号灯超时
  16. CUDA的旋转R ROI Align的OPENCL实现1(原理理解)
  17. 射手影音播放器android,射手影音播放器安卓版
  18. 测试环境的搭建和维护_软硬件测试环境
  19. 二维特征分类的基础_用特征提取技术降低数据集维度,你学会了吗?
  20. 数据库与MPP数仓(十九):高效SQL

热门文章

  1. Android App屏幕旋转要点
  2. 养龟者,养心也(浅析巴西龟的饲养方法)
  3. “知识分享与交流”活动有感
  4. node对文件的读取和修改
  5. 厦大计算机科学系培养方案,计算机科学与技术学术型培养-厦门大学计算机科学系...
  6. 关于微信聊天中的语音开发
  7. SpringCloud版本Hoxton SR5 --- 第三讲:Ribbon 、Ribbon与Feign配合使用
  8. 浅谈WMS系统(SAP WMS系统及非SAP的WMS系统)
  9. 利用定时/计数器T1产生定时时钟,由P1口控制8个发光二极管,使8个提示灯依次一个一个闪动,闪动频率为10次每秒(8个灯亮一遍为一个周期),循环
  10. 根据一段时间区间,按月份拆分成多个时间段