我似乎无法找到解决这个问题的好方法。
假设我在描述角色位置的2D网格上有一个点(棋盘游戏):
[n,m]
现在,每次转弯我都可以根据骰子的滚动(1,2,3 ......)移动角色,我想找到角色可以移动的所有可能方式。
移动角色一次意味着仅更改n
或m
,其中对角线移动计为2次移动(即[n + 1,m]移动一次,[ n + 1,m + 1]移动两次。
例如,如果我滚动2,那么所有可能的动作都是:
[n,m+2]
[n-1,m+1][n,m+1][n+1,m+1]
[n-2,m][n-1,m][n,m][n+1,m][n+2,m]
[n-1,m-1][n,m-1][n+1,m-1]
[n,m-2]
我似乎无法为此获得明确的算法。
到目前为止,Daniel Lew
提出了另一项建议position = [3,2] #position
n = 2 #number of moves allowed
for i in range(position[0]-n,position[0]+n):
for j in range(position[1]-n,position[1]+n):
if abs(position[0]-i) + abs(position[1]-j) <= n:
print i,j,'works\n'
然而,它错过了[n][m+2],[n+2,m]
(或者我写的方式错过了它)。
有关简明答案或修正的任何建议吗?
答案 0 :(得分:1)
穿过(倾斜的)钻石线并转换为法线坐标。 Python代码
n = 2 #number of moves allowed
for i in range(0, n+1):
for j in range(0,n+1):
print i + j - n, i - j,'\n'
替代方法:您可以沿着n
范围内的第一个坐标向两个方向移动。如果剩下一些移动(movesleft
),您可以使用movesleft
步骤沿任意方向移动第二个坐标。第二阶段必须保留奇数(奇偶校验?),因此使用第2步。
伪代码
n_moves = 2
for dy = -n_moves to n_moves do
movesleft = n_moves - Abs(dy)
for dx = - movesleft to movesleft] step 2 do
make_turn(pos_x + dx, pos_y + dy)
n = 2且n = 3的Delphi代码给出了结果
var
n, ml, dx, dy: Integer;
begin
n := 3;
for dy := - n to n do begin
ml := n - Abs(dy);
dx := - ml;
repeat
Memo1.Lines.Add(Format('[%d, %d]', [dy, dx]));
dx := dx + 2;
until dx > ml;
end;
[-2, 0]
[-1, -1]
[-1, 1]
[0, -2]
[0, 0]
[0, 2]
[1, -1]
[1, 1]
[2, 0]
[-3, 0]
[-2, -1]
[-2, 1]
[-1, -2]
[-1, 0]
[-1, 2]
[0, -3]
[0, -1]
[0, 1]
[0, 3]
[1, -2]
[1, 0]
[1, 2]
[2, -1]
[2, 1]
[3, 0]
第一种方法(另一种顺序的结果相同):
for i := 0 to n do
for j := 0 to n do begin
dx := i + j - n;
dy := i - j;
Memo1.Lines.Add(Format('[%d, %d]', [dy, dx]));
end;
[0, -2]
[-1, -1]
[-2, 0]
[1, -1]
[0, 0]
[-1, 1]
[2, 0]
[1, 1]
[0, 2]
答案 1 :(得分:1)
假设骰子显示p。 现在你想知道你当前位置有曼哈顿距离p的点数。 现在你可以做到这一点。
伪代码:
for i=0..p
if( x+i or x-i is valid and y+p-i or y-p+i is valid )
then move in (x+i,y+p-i) or/and (x-i,y-p+i) or/and (x-i,y+p-i) or/and (x-i,y+-i)
答案 2 :(得分:1)
使用Python 2.7:
import math
# Get coordinates of possible dislocations
def get_possible_dislocations(initial_x, initial_y, max_steps):
possible_dislocations = []
for x in range(-max_steps,max_steps+1):
for y in range(-max_steps,max_steps+1):
if math.pow(x, 2) + math.pow(y, 2) <= math.pow(max_steps, 2):
possible_dislocations += [[initial_x + x, initial_y + y]]
return possible_dislocations
print get_possible_dislocations(0,0,2)
# Returns [[-2, 0], [-1, -1], [-1, 0], [-1, 1], [0, -2], [0, -1], [0, 0], [0, 1], [0, 2], [1, -1], [1, 0], [1, 1], [2, 0]]
如果你想用PyGame测试它,你可以这样做:
import math
import pygame, sys
from pygame.locals import *
# Get coordinates of possible dislocations
def get_possible_dislocations(initial_x, initial_y, max_steps):
possible_dislocations = []
for x in range(-max_steps,max_steps+1):
for y in range(-max_steps,max_steps+1):
if math.pow(x, 2) + math.pow(y, 2) <= math.pow(max_steps, 2):
possible_dislocations += [[initial_x + x, initial_y + y]]
return possible_dislocations
# Initialize Pygame
pygame.init()
crashed = False
display_width = 500
display_height = 500
clock = pygame.time.Clock()
display=pygame.display.set_mode((display_width,display_height),0,32)
white=(255,255,255)
blue=(0,0,255)
display.fill(white)
center_w = display_width/2
center_h = display_height/2
# Calculate possible dislocations
possible_dislocations = get_possible_dislocations(center_w, center_h, 50)
# Draw pixels on every possible dislocation, starting from the center of the display
for loc in possible_dislocations:
pygame.draw.rect(display,blue,(loc[0],loc[1],2,2))
# Run the display
while not crashed:
for event in pygame.event.get():
if event.type==QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
clock.tick(60)
在此示例中,角色可以移动50步。如果围绕与中心保持相同距离的点移动,则结果为圆形。如果你可以去那个圆圈内的任何地方,你就可以获得磁盘的笛卡尔坐标。