看到 UP@邻家小女爱数分(https://space.bilibili.com/485356815/dynamic)发的关于四连环流的题目,就想来写一下,看看能不能写出来。
发现还是挺有意思的。不过写得比较烂就是了。。。。。。
# 1
# 8列6行的棋盘
# 4个相邻的棋子在一行/一列/一条斜线
# 2
# 程序玩家劳拉,随机放棋子
# 玩家手动输入棋子的列
#假设用户输入的都是整数,用户输入的数不到1-8之间,程序会提示。
#用户输入的列号满时,程序会提示
#程序玩家,不能放进已满的列
# 3
#棋盘满为平局
# 4
#当前文件夹下 “四连环 Log-XXXXX.txt”,XXXXX表示一个5位的随机数
from prettytable import PrettyTable
import random
from enum import Enum
import logging
#第一步设置loger
log = logging.getLogger()
log.setLevel(logging.DEBUG)
#第二步设置handler
XXXXX = random.randint(10000,99999)
log_file = r"./Log-{}.txt".format(XXXXX)
file_handler = logging.FileHandler(log_file,mode='w+')
file_handler.setLevel(logging.DEBUG)
#第二步加强,加入屏幕输出
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
#第三步,设置格式
formater = logging.Formatter("%(message)s")
file_handler.setFormatter(formater)
stream_handler.setFormatter(formater)
#第四步,把handler添加到logger
log.addHandler(file_handler)
log.addHandler(stream_handler)
NoneValue = None
class Mark(Enum):
Laura = 0
Player = 1
class Const(Enum):
Empty = 0
Full = 1
Column_Empty = 2
Column_Full = 3
EnterError = 4
TurnOver = 7
Win = 8
GameOver = 9
def Trans(x):
if x == 0:
return "O"
elif x == 1:
return "X"
else:
return ""
class Table:
chess_table = [
[NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue],
[NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue],
[NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue],
[NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue],
[NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue],
[NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue,NoneValue]
]
def __init__(self):
self.show()
def add_chess(self,name:str,column:int):
"""
return:
1:正常结束
None:非常正常结束
"""
log.info(f"{name}正在放下旗子......")
if name == "Laura":
mark = Mark.Laura
else:
mark = Mark.Player
if not ((0
log.info("请输入一个大于0,小于9的整数")
return Const.EnterError
column-=1
#选一列放下旗子
for row_index,Row in enumerate(Table.chess_table):
if self.IsFull() == Const.Full:
return Const.GameOver
# Row == Table.chess_table[row_index] ,row_index是行号。
# 从第一行开始放,如果第一行满了就检查i+1行
# column是列号,就是我的输入的参数,如果该位置非真(为空),就可以放下棋子
# 放下棋子后,告诉程序:我已经放下棋子了,可以结束了。不然的话程序会在下一行继续放棋子,直到放满为止。
if Row[column] == NoneValue:
Table.chess_table[row_index][column] = mark.value
if self.IsWin(row_index,column,mark)==Const.Win:
log.info(f"Game Over\n{name} Win~")
self.show()
return Const.Win
self.show()
if self.IsFull() == Const.Full:
return Const.GameOver
return Const.TurnOver
return Const.Column_Full
def IsFull(self):
# 检查棋盘的最后一行,如果全部非空,则表示棋盘已满,结束游戏。
for i in Table.chess_table[5]:
# 如果这个位置非空,即表示整个棋盘没满。
if i==NoneValue:
return Const.Empty
return Const.Full
def IsWin(self,row:int,column:int,mark:Enum)->Enum:
h = self.CheckHorizontal(row,column,mark)
v = self.CheckVertical(row,column,mark)
oup = self.CheckObliqueUp(row,column,mark)
odown = self.CheckObliqueDown(row,column,mark)
if h or v or oup or odown:
return Const.Win
def CheckHorizontal(self,row,column,mark):
horizontal=[]
m = column
i = 4
while i:
if m<0:
break
value = Table.chess_table[row][m]
if value == NoneValue:
break
if value == mark.value:
horizontal.append(value)
i-=1
m-=1
n = column+1
j = 4
while j :
if n>7:
break
value = Table.chess_table[row][n]
if value == NoneValue:
break
if value == mark.value:
horizontal.append(value)
i-=1
n+=1
if len(horizontal)>=4:
log.info(f"horizontal:{horizontal},row:{row}")
return Const.Win
del horizontal
def CheckVertical(self,row,column,mark):
vertical=[]
m = row
i = 4
while i:
if m<0:
break
value = Table.chess_table[m][column]
if value == NoneValue:
break
if value == mark.value:
vertical.append(value)
i-=1
m-=1
n = row+1
j = 4
while j :
if n>5:
break
value = Table.chess_table[n][column]
if value == NoneValue:
break
if value == mark.value:
vertical.append(value)
i-=1
n+=1
if len(vertical)>=4:
log.info(f"vertical:{vertical},column:{column}")
return Const.Win
del vertical
def CheckObliqueUp(self,row,column,mark):
oblique=[]
r = row
c = column
i = 4
while i:
if r<0 or c>7:
break
value = Table.chess_table[r][c]
if value == NoneValue:
break
if value == mark.value:
oblique.append(value)
i-=1
r-=1
c+=1
r2 = row+1
c2 = column+1
j = 4
while j :
if r2>5 or c2<0 or c2>7:
break
value = Table.chess_table[r2][c2]
if value == NoneValue:
break
if value == mark.value:
oblique.append(value)
i-=1
r2+=1
c2-=1
if len(oblique)>=4:
log.info(f"oblique:{oblique},column:{column}")
return Const.Win
del oblique
def CheckObliqueDown(self,row,column,mark):
oblique=[]
r = row
c = column
i = 4
while i:
if r<0 or c>7:
break
value = Table.chess_table[r][c]
if value == NoneValue:
break
if value == mark.value:
oblique.append(value)
i-=1
r-=1
c-=1
r2 = row+1
c2 = column+1
j = 4
while j :
if (r2>5) or (c2<0) or (c2>7):
break
value = Table.chess_table[r2][c2]
if value == NoneValue:
break
if value == mark.value:
oblique.append(value)
i-=1
r2+=1
c2+=1
if len(oblique)>=4:
log.info(f"oblique:{oblique},column:{column}")
return Const.Win
del oblique
def show(self):
tb = PrettyTable()
tb.field_names = [str(i+1) for i in range(8)]
for i,j in enumerate(Table.chess_table):
j = [k for k in map(Trans,j)]
tb.add_row(j)
log.info(f"\n{tb}")
del tb
def LauraTurn(t:Table):
name = "Laura"
while 1:
col = random.randint(1,8)
x = t.add_chess(name,col)
# 如果添加棋子是正常结束的话,就跳出循环,完成这一轮的工作。
# 否则的话就要再执行一次添加棋子的工作,直到该动作正常结束为止。
if x == Const.Column_Full:
log.info(f"col:{col}已满,请把棋子放到其它列。")
continue
elif x == Const.EnterError:
continue
elif x == Const.GameOver:
return Const.GameOver
elif x == Const.TurnOver:
return Const.TurnOver
elif x == Const.Win:
return Const.Win
def MyTurn(t:Table,name:str="Player"):
while 1:
while 1:
col = input("现在轮到你下棋了,请输入一个1-8的整数:").strip()
if col.isdecimal():
col = int(col)
break
elif col == "exit":
return Const.GameOver
x = t.add_chess(name,col)
if x == Const.Column_Full:
log.info(f"col:{col}已满,请把棋子放到其它列。")
continue
elif x == Const.EnterError:
continue
elif x == Const.GameOver:
return Const.GameOver
elif x == Const.TurnOver:
return Const.TurnOver
elif x == Const.Win:
return Const.Win
def main():
msg = """
HI,我是劳拉,我们来玩一局四连环。我用O型棋子,你用X型棋子。\n
游戏规则:双方轮流选择棋盘的列号放进自己的棋子,
若棋盘上四颗相同型号的棋子在一行|一列|一条斜线上连接起来,
则使用该型号棋子的玩家就赢了。\n
开始了,这是棋盘的初始状态:
"""
log.info(msg)
t = Table()
while 1:
x = MyTurn(t)
if x==Const.GameOver:
break
elif x==Const.Win:
break
y = LauraTurn(t)
if y == Const.GameOver:
break
elif y==Const.Win:
break
log.info("Game Over ~")
main()