python - 与“简单”国际象棋相关的随机代码作斗争
问题描述
我的任务是创建一个应该在棋盘上随机放置两个棋子的代码
棋盘看起来像这样:棋盘
我应该做的是在上面的这个棋盘上“放置”两个随机选择的棋子(一个黑色,一个白色),并根据国际象棋规则找出这些棋子是否落在它们会相互威胁的地方。我应该重复这 10 000 次,并找出遇到威胁情况的频率。棋子不应落在同一个方格中。
有两种不同的场景:
3a。棋子是车(塔) - 水平或垂直移动或 3b。棋子是皇后 - 水平、垂直和对角移动或
我的假设是 3a 中的方法应该是,如果两个棋子的第一个数字或最后一个数字相同,则情况会造成威胁。我会使用随机函数为这两个部分分配随机数并运行 10K 次。我不确定如何构建此代码来确定棋子是否对彼此造成威胁。如何使用棋盘(11-88)定义随机数?
另一方面,3b 的方法是一个很大的问号,因为皇后也可以对角移动。
我真的很感激一些代码示例来了解如何解决这个问题。谢谢!
编辑:下面是我使用迄今为止获得的技能自己生成的代码。我相信这给了我一个皇后威胁另一个皇后的频率的答案,但它没有考虑到棋子不能放在棋盘上的同一个方格上。如果代码在其他方面是正确的,我怎么能在我的代码中实现它?我想尽可能少地修改它。
import random
rows=range(1,9) #generates the row number
columns=range(97,97+8) #generates the column number
hot=0 #times threat took place
icke_hot=0 #times threat did not take place
for spel in range(10000):
white_row=random.choice(rows) #Gets position in row
black_row=random.choice(rows)
white_column=random.choice(columns) #Gets position in column
black_column=random.choice(columns)
if white_column==black_column or white_row==black_row: #checks if rook can attack
hot=hot+1
elif white_column==black_column or white_column==black_column+1 or white_column==black_column-1:
hot=hot+1
#checks if queen can attack
elif white_row==black_row or white_row==black_row+1 or white_row==black_row-1:
hot=hot+1
#checks if queen can attack
else:
icke_hot=icke_hot+1
print "Threats took place in", hot/100.0,"% of cases"
print hot
print icke_hot
解决方案
对 OP 代码的评论
列编号有问题
columns=range(97,97+8) #generates the column number 97, 98, ...
你可以使用
columns = [chr(i) for i in range(97,97+8)
下一代的行/列不能确保白色和黑色没有分配到同一个正方形。
white_row=random.choice(rows) #Gets position in row
black_row=random.choice(rows)
white_column=random.choice(columns) #Gets position in column
black_column=random.choice(columns)
最好将位置定义为行和列对,然后使用 random.choices 或 random.sample 随机选择 64 个位置中的两个
此代码不会检查沿对角线的所有位置以进行女王攻击。
elif white_column==black_column or white_column==black_column+1 or white_column==black_column-1:
hot=hot+1
#checks if queen can attack
elif white_row==black_row or white_row==black_row+1 or white_row==black_row-1:
hot=hot+1
#checks if queen can attack
修订代码
import random as random
def all_positions():
" Generates list of all piece positions (i.e. 64 positions) "
rows = '12345678'
columns = 'abcdefgh'
return [r+c for r in rows for c in columns] # i.e. ['1a', '1b', ...]
def random_positions():
" Two random positions (not equal) "
# Use random sample without replacement
return random.sample(all_positions(), 2)
def position_to_numeric(position):
" Convert row, column string to numeric tuple i.e. '3a -> 3, 1 "
return int(position[0]), 'abcdefgh'.index(position[1]) + 1
def can_rook_attack(position1, position2):
" Do rooks at position1 and position2 attack each other "
return position1[0] == position2[0] or position1[1] == position2[1]
def can_queen_attack(position1, position2):
" if queens at position 1 & 2 can attack each other "
# Check as rooks they would attack
if can_rook_attack(position1, position2):
return True
# Get positions as numeric
r1, c1 = position_to_numeric(position1)
r2, c2 = position_to_numeric(position2)
# If queen and the opponent are
# If queen can attack diagonally
return abs(r1 - r2) == abs(c1 - c2)
def simulate_rooks(number_trials):
" Simulate of how often rook can attack "
cnt = 0
for _ in range(number_trials):
position1, position2 = random_positions()
if can_rook_attack(position1, position2):
cnt += 1
return f'Rook attacked {cnt} out of {number_trials} random placements'
def simulate_queens(number_trials):
" Simulate of how often queens can attack "
cnt = 0
for _ in range(number_trials):
position1, position2 = random_positions()
if can_queen_attack(position1, position2):
cnt += 1
return f'Queen attacked {cnt} out of {number_trials} random placements'
测试
simulations = 10000
print(simulate_rooks(simulations))
print(simulate_queens(simulations))
输出
Rook attacked 2257 out of 10000 random placements
Queen attacked 3634 out of 10000 random placements
解释
关键问题
- 我应该做的是在上面的这个棋盘上“放置”两个随机选择的棋子(一个黑色,一个白色),并根据国际象棋规则找出这些棋子是否落在它们会相互威胁的地方。我应该重复这 10 000 次,并找出遇到威胁情况的频率。棋子不应落在同一个方格中。
这是在simulate_rooks 和simulate_queens 中使用以下代码完成的
for _ in range(number_trials):
position1, position2 = random_positions()
其中 random_positions 使用 random.sample (不替换)从所有可能的位置中选择两个位置
- 我的假设是 3a 中的方法应该是,如果两个棋子的第一个数字或最后一个数字相同,则情况
这是通过 can_rook_attack 中的代码完成的
return position1[0] == position2[0] or position1[1] == position2[1]
- 另一方面,3b 的方法是一个很大的问号,因为皇后也可以对角移动。
这可以使用以下方法解决:
return abs(r1 - r2) == abs(c1 - c2)
这使用了沿对角线斜率必须为 +/-1 的约束,这导致了上述表达式。
推荐阅读
- xml - 如何在 wagtail 中导入 xml 文件或从 wordpress 迁移到 wagtail
- javascript - 验证数组的所有对象中的属性值是否为假,并从数组的前三个最大对象中选择属性值
- c - 我的 HashTable 中的指针损坏或我遗漏了什么?
- python - How to plot two or more labels of one word in matplotlib?
- flutter - Flutter LinearProgressIndicator 未加载
- android - 如何使 FloatingActionButton 可拖动?
- azure - Azure Function App 无法读取带有队列触发器的 Base64 编码消息
- azure - WEBSITE_RUN_FROM_PACKAGE 参数设置为 1 后,如何在 Azure 门户上编辑 Azure 功能代码?
- python - 无法点安装手电筒
- excel - 在 Excel 的散点图中添加 ± 10 % 的线