Python实现黑白棋人机对弈

规则

黑白棋的每颗棋子由黑白两色组成,一面白,一面黑。每次落子,把本方颜色的棋子放在棋盘的空格上,若在横、竖、斜八个方向的任一方向上有本方棋子,则被夹在中间的对手棋子全部翻转为本方棋子颜色;并且,仅在可以翻转棋子的地方才能落子。如果一方至少有一步合法棋步可下,他就必须落子,不得弃权。棋盘已满或双方都没有棋子可下时棋局结束,以棋子数目来计算胜负,棋子多的一方获胜。在棋盘还没有下满时,如果一方的棋子已经被对方吃光,则棋局也结束,将对手棋子吃光的一方获胜。

两位玩家轮流下棋,直到一方没有符合规则的落子位置,在这种情况下,剩下的一方继续下棋,直到对手有了可以落子的位置。此时,恢复两者轮流下棋的顺序。如果一方落子在非法位置,则视为放弃本次对弈,对方获胜。游戏结束的条件:1)整个棋盘满了;2)一方的棋子已经被对方吃光;3)两名玩家都没有可以落子的棋盘格;4)一方落子在非法位置。前3 种情况以棋子数目来计算胜负,棋子多的一方获胜;第4 种情况判定对方获胜。

计算机选择落子位置的策略

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

实现思路

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

亟待完善的地方

机器下棋策略可以改善,设计递推方法

不同的持棋方式写了重复的代码,可以进一步包装

无效代码可以删除,如cont,

命名

import time

import csv

class 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 = 0

def __init__(self, dim, players, _color): # _color只能是hei or bai ,players只能是com or peop

self.hei = {(dim//2+1, dim//2), (dim//2, dim//2+1)}

self.players = players

self.bai = {(dim//2, dim//2), (dim//2+1, dim//2+1)}

self.dim = dim

self._color = _color # dic

def 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.bai

else:

_players = self.hei

kong = [(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 = 1

lst = []

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 += 1

if (p[0] + i * r[0], p[1] + i * r[1]) in players:

_players_list_in += lst

break

if i > self.dim + 1:

break

else:

break

if _players_list_in: # 如果这个方向有jiazai中间的反色子

all_r_players_list_in += _players_list_in

if 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_in

def callback(self):

'''

根据对象不同选择不同的下棋方式

:return: 机器下棋还是人工下棋

'''

if self.players == 'com':

return self.computer_xia

if self.players == 'peop':

return self.players_xia

def color(self):

if self._color == 'hei':

return self.hei

return self.bai

def hefa(self,players, p):

'''

测试某一位置是否合法,如果合法,返回相应反转的子的位置,不合法返回False

:param p: 位置元组

:return:列表

'''

if p in self.legal_position(players).keys():

return self.legal_position(players)[p]

return False

def 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 = False

else:

self.status = True

p_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 = False

else:

self.status = True

try:

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 = True

except 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 = True

def 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.bai

com.hei = peop.hei

color_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 = True

com.count = 0

print('==' * 5)

print('机器下棋位置:反转对方位置', dic)

com.change(dic)

# print(com.hei, com.bai)

com.qp_print()

if not peop.status:

peop.status = True

def peop_turn():

'''

人下棋

:return:

'''

peop.bai = com.bai

peop.hei = com.hei

color_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 = True

peop.count = 0

print('=='*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 = 0

peop.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()))

break

peop_turn()

if peop.defeat:

print('Invalid move.\nGame over.')

print('com win')

score = 'Human give up'

break

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()))

break

peop.qp_print()

if peop._color == 'hei':

count = 0

peop.qp_print()

while 1:

peop_turn()

if peop.defeat:

print('Invalid move.\nGame over.')

print('com win')

score = 'Human give up'

break

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()))

break

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(peop.color())) +':'+ str(len(com.color()))

break

peop.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)

1544455193(1).jpg

1544455180(1).jpg

黑白棋python代码框架_Python实现黑白棋人机对弈相关推荐

  1. google python代码规范_Python代码这样写才规范优雅! (二)

    前文传送门:Python代码这样写才规范优雅! (一)参考:https://www.python.org/dev/peps/pep-0008/Python PEP8编码规范的内容如下: 1. Intr ...

  2. python gui框架_Python的GUI框架PySide的安装配置教程

    (一)说在前面 Python自带了GUI模块Tkinter,只是界面风格有些老旧.另外就是各种GUI框架了. 之前安装过WxPython,并做了简单的界面.遂最近又重新搜索了一下网上关于Python ...

  3. python数据处理框架_python 最快 web 框架 Sanci 快速入门

    简介 Sanic 是一个和类Flask 的基于Python3.5+的web框架,它编写的代码速度特别快. 除了像Flask 以外,Sanic 还支持以异步请求的方式处理请求.这意味着你可以使用新的 a ...

  4. python 服务器框架_python 服务器框架

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 而我的想法是,掌握一个类似于框架的高级工具是有用的,但是基础的东西可以让你永远不 ...

  5. python twisted框架_Python的Twisted框架上手前所必须了解的异步编程思想

    前言最近有人在Twisted邮件列表中提出诸如"为任务紧急的人提供一份Twisted介绍"的需求.值得提前透露的是,这个系列并不会如他们所愿.尤其是介绍Twisted框架和基于Py ...

  6. python 服务框架_Python Web服务高并发框架【1】(Tornado)

    本节学习目标: (1)了解Tornado的特点 (2)了解Tornado工作流程 (3)掌握Tornado在Window及Linux中的安装 (4)理解同步.异步 (5)协程基础编程 本节课程内容: ...

  7. python事件驱动框架_python事件驱动

    广告关闭 提供包括云服务器,云数据库在内的50+款云计算产品.打造一站式的云产品试用服务,助力开发者和企业零门槛上云. 事件循环轮询所有的事件,当事件到来时将它们分配给等待处理事件的回调函数. 这种方 ...

  8. python基础框架_Python基础框架和工具-阿里云开发者社区

    Python基础框架和工具 最近在学Python金融大数据分析,在安装Python进行大数据分析的环境时遇到很多问题,例如:在安装pandas包时候就要到各种错误,总是缺少很多安装包,最后发现利用Py ...

  9. python任务调度框架_Python任务调度模块APScheduler

    一.APScheduler 是什么&APScheduler四种组成部分? APScheduler全程为Advanced Python Scheduler,是一款轻量级的Python任务调度框架 ...

最新文章

  1. Octavia 创建 loadbalancer 的实现与分析
  2. ckks方案优化最好的_果断收藏:SEO高级优化技能升级策略!
  3. 【Javascript】 DOM节点
  4. java定义基础变量语句_java语言基础-变量
  5. 网络爬虫--25.【selenium实战】实现拉勾网爬虫之--selenium获取数据
  6. 7-Arco大讲堂(二)
  7. spring aop获取目标对象的方法对象(包括方法上的注解)(转)
  8. 从RCNN到SSD,深度学习目标检测算法盘点
  9. 关于js中window.location.href、location.href、parent.location.href、top.location.href的用法...
  10. python 打包_Python 打包指南
  11. Python借助smote实现不均衡样本数据的上采样和下采样,并可视化展示样本分布
  12. 虚幻引擎5安装踩坑记录
  13. 开网店,网店系统的编程语言分析
  14. 天涯论坛_全球华人网上家园_天涯社区
  15. git具体作用_GIT的工作原理、功能特点及其运用
  16. 转载 | 身份访问与管理(IAM)的定义、应用与提供商
  17. 分布式系统设计模式,你用过哪些?
  18. JETSON TX2烧写系统
  19. Xilinx AXI USB2.0 Device IP 手册阅读笔记
  20. java gui程序设计_JAVA进行GUI程序设计之一

热门文章

  1. Android界面编程之利用单选框和复选框实现对学历和爱好进行选择
  2. 谢慧敏清晰版. 数学分析习题课讲义.下. 2004
  3. 最全4k,8k的高清壁纸网站免费下载
  4. 王者荣耀产品分析(本人不是产品,只是自己分析了一下)
  5. 一个软件工程师的7年工作经验总结
  6. godot学习笔记1前期摸索
  7. Initialization failed for ‘https://start.spring.io
  8. 标签体系-内容建设思路
  9. 2022年卡塔尔世界杯,分析之前的比赛计算出谁是冠军
  10. 当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'Logger' 中的标识列插入显式值