首页 > 解决方案 > 与“简单”国际象棋相关的随机代码作斗争

问题描述

我的任务是创建一个应该在棋盘上随机放置两个棋子的代码

棋盘看起来像这样:棋盘

我应该做的是在上面的这个棋盘上“放置”两个随机选择的棋子(一个黑色,一个白色),并根据国际象棋规则找出这些棋子是否落在它们会相互威胁的地方。我应该重复这 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

标签: pythonrandom

解决方案


对 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

解释

关键问题

  1. 我应该做的是在上面的这个棋盘上“放置”两个随机选择的棋子(一个黑色,一个白色),并根据国际象棋规则找出这些棋子是否落在它们会相互威胁的地方。我应该重复这 10 000 次,并找出遇到威胁情况的频率。棋子不应落在同一个方格中。

这是在simulate_rooks 和simulate_queens 中使用以下代码完成的

for _ in range(number_trials):
    position1, position2 = random_positions()

其中 random_positions 使用 random.sample (不替换)从所有可能的位置中选择两个位置

  1. 我的假设是 3a 中的方法应该是,如果两个棋子的第一个数字或最后一个数字相同,则情况

这是通过 can_rook_attack 中的代码完成的

return position1[0] == position2[0] or position1[1] == position2[1]
  1. 另一方面,3b 的方法是一个很大的问号,因为皇后也可以对角移动。

这可以使用以下方法解决:

return abs(r1 - r2) == abs(c1 - c2) 

这使用了沿对角线斜率必须为 +/-1 的约束,这导致了上述表达式。


推荐阅读