Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Elixir中从地图集中的坐标(如0,0)打印栅格?_Elixir - Fatal编程技术网

如何在Elixir中从地图集中的坐标(如0,0)打印栅格?

如何在Elixir中从地图集中的坐标(如0,0)打印栅格?,elixir,Elixir,我正在学习长生不老药通过建立一个简单的井字游戏。现在我设置它的方法是在棋盘上有玩家选择单元,如{col,row}所以{0,0},{1,2}等等。所有的移动都存储在一个名为turns的地图集中 %TTT{turns: %{x: MapSet.new, o: MapSet.new}, last_player: :player} 我已经完成了基本游戏逻辑的实现,但是我很难尝试构建一个简单的游戏命令行表示,尤其是在显示棋盘的当前状态时。有什么建议吗?对于基于坐标的板,我通常使用{col,row}键将板

我正在学习长生不老药通过建立一个简单的井字游戏。现在我设置它的方法是在棋盘上有玩家选择单元,如
{col,row}
所以
{0,0}
{1,2}
等等。所有的移动都存储在一个名为turns的
地图集中

%TTT{turns: %{x: MapSet.new, o: MapSet.new}, last_player: :player}

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

对于基于坐标的板,我通常使用{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

对于基于坐标的板,我通常使用{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

@史蒂夫·帕伦(Steve Pallen)给出了一个很好的回答,但我想指出使用a而不是常规模块的好处:它允许使用
handle\u 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

TictaToe使用该系统的一个例子是可用的。

@Steve Pallen给出了一个很好的答案,但是我想指出使用一个而不是常规模块的好处:它将允许使用
handle\u 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
使用该系统的tictactoe示例可用