• Elixir游戏服设计六


    接上章,我新建了个app做包含Table模型, TableServer等。Table桌子的代码暂时如下, 有一些状态还没用上

    defmodule Table do
        
        @state_accept 0   #准备接入玩家
        @state_ready 1    #开局准备?
        defdelegate [fetch(t, key), get_and_update(t, key, list)], to: Map
        defstruct [:config, :seats, :state]
        def new(config) do
            %Table{
                config: config,
                seats: %{},
                state: @state_accept
            }
        end
    
        def is_full?(table) do
            cur_count = Enum.count(table.seats)
            cur_count >= table.config.allow_count
        end
    
        def has_player?(table, player_id) do
            table.seats[player_id]
        end
    
        def check_in(table, player) do
            update_in(table.seats, &(Map.put(&1, player.base_info.id, player)))
        end
    
        def check_out(table, player_id) do
            update_in(table.seats, &(Map.delete(&1, player_id)))
        end
    end

    我们需要相关的配置table_config.txt

    id,     allow_count,   base_gold,   need_gold,     desc
    int,    int,           int,         int,        string
    1,      4,             10,          480,         新手场
    2,      4,             100,         4800,        中级场
    3,      4,             1000,        48000,       高级场

    这个txt可以由excel通过xslx2csv工具生成。然后我们利用table_config.txt 生成代码配置table_config.ex.

    我们当然可以在TableConfig里经由excel文件直接生成,那样会更方便。

    defmodule TableConfig do
        Module.register_attribute __MODULE__, :column_names, []
        Module.register_attribute __MODULE__, :column_types, []
        Module.register_attribute __MODULE__, :config, []
        line_with_index = File.stream!(Path.join([__DIR__, "table_config.txt"]) , [], :line) 
                          |> Stream.with_index
        for {line, index} <- line_with_index do
            items = line |> String.split(",") |> Stream.map(&String.strip(&1)) 
            case index do
                0 ->
                    @column_names items |> Enum.map(&String.to_atom(&1))
                1 ->
                    @column_types items 
                                  |> Stream.with_index 
                                  |> Enum.map(fn {v, i} -> {i, String.to_atom(v)} end)
                                  |> IO.inspect
                                  |> Enum.into(%{})
                _ ->
                    new_items = items 
                                |> Stream.with_index
                                |> Stream.map( &( TypeConverter.convert(&1, @column_types) ) )    
                    zip = Enum.zip(@column_names, new_items)
                    @config  Enum.into(zip, %{})
                    IO.inspect @config
           # 以下函数花了我点时间,最后不得不通过模块属性完成,我不知道有没有其他方法
             # 早期的版本是者这样的
    # config = Enum.into(zip, %{})
    # def get(unquote(config.id)) do
    #   unquote(config) # 这里会报错,百思不得其解,在ErrorMsg里我是这样用的,没有问题。不知2者区别在哪
    # end
    def get(unquote(@config.id)) do @config end end end end

    最后上点测试代码table_test.exs

    defmodule TabelTest do
      use ExUnit.Case
      # import PipeHere
      setup do
          config = TableConfig.get(1)   
          table = Table.new(config)
          {:ok, table: table}
      end
    
      test "table is full ", %{table: table} do
          new_table =
            1..table.config.allow_count 
            |> Stream.map(&Player.new/1)
            |> Enum.reduce(table, fn p, acc -> Table.check_in(acc, p) end)
        assert new_table |> Table.is_full?
      end
    
      test "table has player", %{table: table} do
           p1 = Player.new(1)
           p2 = Player.new(2)
           new_table = Table.check_in(table, p1)
           assert Table.has_player?(new_table, p1.base_info.id)
           refute Table.has_player?(table, p2.base_info.id)
      end
    
      test "table check_in_and_out", %{table: table} do
            p1 = Player.new(1)
            new_table = Table.check_in(table, p1)
            check_out_table = Table.check_out(new_table, p1.base_info.id)
            refute Table.has_player?(check_out_table, p1.base_info.id)
      end
    end

    下一小节会从牌局开始吧,然后TableServer,然后让它跑起来。

  • 相关阅读:
    阿里巴巴图标库在项目中的用法
    js对象的深拷贝
    Ajax
    HTML5新增的canvas是什么--通过刮奖效果学习
    一些最基础的面试题
    微信小程序实现列表搜索功能
    vue的基础双向绑定
    ES6 Promise 的不完全实现
    JQ学习
    播放音乐进度条
  • 原文地址:https://www.cnblogs.com/rubyist/p/5549749.html
Copyright © 2020-2023  润新知