如何在Elixir的MapSet中从坐标(如0、0)打印网格?

时间:2018-07-14 20:09:39

标签: elixir

我正在通过构建一个简单的井字游戏来学习Elixir。现在,我设置的方式是将棋盘上的玩家选择单元格设置为{col, row},因此{0, 0}{1, 2}等将所有移动存储在{{1 }}称为转弯。

MapSet

我已经完成了基本的游戏逻辑,但是我很难建立一个简单的游戏命令行表示,特别是在显示棋盘的当前状态时。有什么建议吗?

2 个答案:

答案 0 :(得分:1)

对于基于坐标的板,我通常使用{col,row}键将板创建为地图。

这是具有打印功能的示例板:

defmodule Ttt do
  def new_board do
    for col <- 1..3, row <- 1..3, into: %{}, do: {{col, row}, " "}
  end

  def put(board, {col, row}, val) do
    put(board, col, row, val)
  end

  def put(board, col, row, val), do: Map.put(board, {col, row}, val)

  def fill(board, list, which) do
    Enum.reduce(list, board, fn point, acc -> put(acc, point, which) end)
  end

  def fill_example_1(board) do
    xs = [{1, 1}, {2, 2}, {3, 3}]
    ys = [{2, 1}, {3, 1}, {1, 2}]

    board
    |> fill(xs, "X")
    |> fill(ys, "O")
  end

  def print(board) do
    for row <- 1..3 do
      for col <- 1..3 do
        " " <> board[{col, row}]
      end
      |> Enum.join(" |")
    end
    |> Enum.join("\n---+---+---\n")
    |> IO.puts()
  end

  def run do
    new_board()
    |> fill_example_1()
    |> print
  end
end

输出:

 iex(2)> Ttt.run()
 X | O | O
---+---+---
 O | X |
---+---+---
   |   | X
:ok

答案 1 :(得分:1)

@Steve Pallen提供了一个很好的答案,但是我想指出使用GenServer而不是常规模块的好处:它将允许使用handle_info回调来显示面板。长生不老药的这一功能具有许多优点:

  • 该显示将永久自动刷新。
  • 分发更加容易:例如,如果每个玩家都在自己的计算机上玩,则无需调用功能即可检查其他玩家是否玩过:它会自动出现在显示屏上感谢GenServer
  • 您可以使用主管,并充分利用长生不老药的让其崩溃哲学

下面的代码可以使您了解如何执行此操作:

defmodule Tictactoe do
    use GenServer

    def start_link(opts), do: GenServer.start_link(__MODULE__, :ok, opts)

    def init(:ok) do
        schedule_work()
        {:ok, state}
    end


    # ...
    # game code + print function defined in Steve Pallen's answer
    # ...

    def handle_info(:work, state) do
      print(state) # use function defined by Steve Pallen above
      schedule_work()
      {:noreply, state}
    end

    # function used by the callback to refresh display every 100ms
    defp schedule_work(), do: Process.send_after(self(), :work, 100)

end

here提供了使用该系统的针线虫的示例。