在 Elixir 上输出一个简单的棋盘游戏,但变量不是递减的。如何解决这个问题?
Outputting a simple board game on Elixir, but a variable is not decrementing. How to fix this?
我有一个名为 main(row,col) 的函数,它将接受 2 个整数并将它们分别放入 row 和 col 中。然后它将创建一个板的输出,因此 main(2,3) 将创建一个 2 x 3 板。
spaces= row*col
所以在这种情况下,每次创建单元格时,spaces=6 并且应该减 1。但是它不会这样做。我 运行 时的输出是
Main.main(2,3)
+---+---+---+
| 6| 6| 6|
| | | |
+---+---+---+
| 6| 6| 6|
| | | |
+---+---+---+
我需要它
Main.main(2,3)
+---+---+---+
| 6| 5| 4|
| | | |
+---+---+---+
| 3| 2| 1|
| | | |
+---+---+---+
这是我的代码:
defmodule Main do
def main(row,col) do
spaces = row*col
for i <- 0..(row-1) do
for j <- 0..(col-1) do
if j == 0 do
IO.write "+"
end
IO.write "---+"
end
IO.puts ""
columns = col
for columns <- 1..columns do
if columns == 1 do
IO.write "|"
end
if spaces < 10 do
IO.write " "
IO.write spaces
IO.write "|"
else if spaces < 100 do
IO.write " "
IO.write spaces
IO.write "|"
end
if spaces > 99 do
IO.write spaces
IO.write "|"
end
spaces = (spaces - 1)
end
end
IO.puts ""
columns = col
for columns <- 1..columns do
if columns == 1 do
IO.write "|"
end
IO.write" |"
end
IO.puts ""
if i == row-1 do
botside = col
for botside <- 1..col do
if botside == 1 do
IO.write "+"
end
IO.write "---+"
end
end
end
end
end
如您所见,
spaces =(spaces - 1)
无论出于何种原因都没有递减。感谢您的时间和帮助。
行
spaces = (spaces - 1)
被置于推导式中并没有达到您的预期。它将新的局部变量 spaces
声明为最外层的 spaces
减一。这个局部变量 spaces
,尽管它与最外层变量同名,但在理解结束时死亡。
整个代码都不是灵丹妙药惯用的,很难在这里提出任何优雅的解决方案。一般来说,在 Elixir 中是要避免状态的。
作为拼凑,您可能会使用:
spaces = spaces + 1 - columns
正如@mudasobwa 指出的那样,很难告诉您如何解决这个问题,因为它从根本上与函数式编程中通常的做法背道而驰。
也就是说,这里有一个示例,说明您可以在 Elixir 中实现递减循环:
defmodule Test do
def decrementing_loop(initval) do
IO.inspect initval
if (initval > 0) do
decrementing_loop(initval-1)
end
end
end
除非您可能想将一个函数传递给 decrementing_loop
——像这样:
defmodule Test do
def decrementing_loop(initval, f) do
f.(initval)
if (initval > 0) do
decrementing_loop(initval - 1, f)
end
end
end
然后会这样调用:
Test.decrementing_loop(10,&IO.inspect/1)
重点是我实际上并没有修改 initval
,而是将当前 initval-1
的新参数传递给函数的递归调用。
综上所述,恕我直言,如果您认真学习 Elixir,那么明智的做法是投资一本好书,而不是通过在这里提出一系列问题来试图蚕食其中的一部分。
首先创建列表是我的意思
rows=3
cols=2
top = rows*cols
labels = Enum.to_list top..1 # [6,5,4,3,2,1]
c = Enum.to_list 1..rows # [1,2,3]
c = List.duplicate c, cols # [[1,2,3],[1,2,3]]
c = List.flatten c # [1,2,3,1,2,3]
r = Enum.to_list 1..cols # [1,2]
r = List.duplicate r, rows #[[1,2],[1,2],[1,2]]
r = List.flatten r # [1,2,1,2,1,2]
list = List.zip( [r, c, labels] )
board = list |> Enum.each( fn {r,c,label} -> print_cell r,c, label, rows, cols end)
defp print_cell r,c, label, rows,cols do
# your conditional cases for each edge case here
end
我有一个名为 main(row,col) 的函数,它将接受 2 个整数并将它们分别放入 row 和 col 中。然后它将创建一个板的输出,因此 main(2,3) 将创建一个 2 x 3 板。
spaces= row*col
所以在这种情况下,每次创建单元格时,spaces=6 并且应该减 1。但是它不会这样做。我 运行 时的输出是
Main.main(2,3)
+---+---+---+
| 6| 6| 6|
| | | |
+---+---+---+
| 6| 6| 6|
| | | |
+---+---+---+
我需要它
Main.main(2,3)
+---+---+---+
| 6| 5| 4|
| | | |
+---+---+---+
| 3| 2| 1|
| | | |
+---+---+---+
这是我的代码:
defmodule Main do
def main(row,col) do
spaces = row*col
for i <- 0..(row-1) do
for j <- 0..(col-1) do
if j == 0 do
IO.write "+"
end
IO.write "---+"
end
IO.puts ""
columns = col
for columns <- 1..columns do
if columns == 1 do
IO.write "|"
end
if spaces < 10 do
IO.write " "
IO.write spaces
IO.write "|"
else if spaces < 100 do
IO.write " "
IO.write spaces
IO.write "|"
end
if spaces > 99 do
IO.write spaces
IO.write "|"
end
spaces = (spaces - 1)
end
end
IO.puts ""
columns = col
for columns <- 1..columns do
if columns == 1 do
IO.write "|"
end
IO.write" |"
end
IO.puts ""
if i == row-1 do
botside = col
for botside <- 1..col do
if botside == 1 do
IO.write "+"
end
IO.write "---+"
end
end
end
end
end
如您所见,
spaces =(spaces - 1)
无论出于何种原因都没有递减。感谢您的时间和帮助。
行
spaces = (spaces - 1)
被置于推导式中并没有达到您的预期。它将新的局部变量 spaces
声明为最外层的 spaces
减一。这个局部变量 spaces
,尽管它与最外层变量同名,但在理解结束时死亡。
整个代码都不是灵丹妙药惯用的,很难在这里提出任何优雅的解决方案。一般来说,在 Elixir 中是要避免状态的。
作为拼凑,您可能会使用:
spaces = spaces + 1 - columns
正如@mudasobwa 指出的那样,很难告诉您如何解决这个问题,因为它从根本上与函数式编程中通常的做法背道而驰。
也就是说,这里有一个示例,说明您可以在 Elixir 中实现递减循环:
defmodule Test do
def decrementing_loop(initval) do
IO.inspect initval
if (initval > 0) do
decrementing_loop(initval-1)
end
end
end
除非您可能想将一个函数传递给 decrementing_loop
——像这样:
defmodule Test do
def decrementing_loop(initval, f) do
f.(initval)
if (initval > 0) do
decrementing_loop(initval - 1, f)
end
end
end
然后会这样调用:
Test.decrementing_loop(10,&IO.inspect/1)
重点是我实际上并没有修改 initval
,而是将当前 initval-1
的新参数传递给函数的递归调用。
综上所述,恕我直言,如果您认真学习 Elixir,那么明智的做法是投资一本好书,而不是通过在这里提出一系列问题来试图蚕食其中的一部分。
首先创建列表是我的意思
rows=3
cols=2
top = rows*cols
labels = Enum.to_list top..1 # [6,5,4,3,2,1]
c = Enum.to_list 1..rows # [1,2,3]
c = List.duplicate c, cols # [[1,2,3],[1,2,3]]
c = List.flatten c # [1,2,3,1,2,3]
r = Enum.to_list 1..cols # [1,2]
r = List.duplicate r, rows #[[1,2],[1,2],[1,2]]
r = List.flatten r # [1,2,1,2,1,2]
list = List.zip( [r, c, labels] )
board = list |> Enum.each( fn {r,c,label} -> print_cell r,c, label, rows, cols end)
defp print_cell r,c, label, rows,cols do
# your conditional cases for each edge case here
end