上回介绍了玩法,现在编写了玩法的简单建模。

做到现在感觉目前还没有使用umbrella的必要(也许以后会发现必要吧),model 应用完全可以合并到game_server。

代码还在https://github.com/rubyist1982/simple 上。

model 应用新增 simple_poker.ex , 代码不多,做了点简单注释,可以贴下

defmodule SimplePoker do
@cards for i <- 1..4, j<- 1..13, do: {i, j}
@ten 10
@ace 1
@tian_gong [8,9]
@ignore 0
def init_cards, do: @cards
# 洗牌
def shuffle(cards), do: cards |> Enum.shuffle # 初始发牌
def init_deal(cards, seat_num) do
{cs, left} = cards |> Enum.split(seat_num * 2)
{:ok, Enum.chunk_every(cs, 2), left}
end # 补单张
def deal([card| left]), do: {:ok, card, left} def single_point({_, p}) when p < @ten, do: p
def single_point(_), do: @ten def normal_power(cards) do
sum = cards |> Enum.map( &single_point(&1) ) |> Enum.sum
rem(sum, @ten)
end
# 牌力计算, 需参考是否开牌
def power([_a, _b] = cards, is_open) do
p = normal_power(cards)
cond do
p in @tian_gong and is_open -> {:tian_gong, p}
true ->{:normal, p}
end
end def power(cards, false) do
cond do
is_flush_straight?(cards) -> {:flush_straight, @ignore}
is_three?(cards) -> {:three, @ignore}
is_flush?(cards) -> {:flush, @ignore}
is_straight?(cards) -> {:straight, @ignore}
true -> {:normal, normal_power(cards)}
end
end # a 是否赢 b
# 都是天公,比点数
def win?({:tian_gong, p1}, {:tian_gong, p2}), do: p1 > p2
# 天公比其他都大
def win?({:tian_gong, _}, _), do: true
def win?(_, {:tian_gong, _}), do: false # 非普通牌,通牌型一样大
def win?({same, _}, {same, _}) when same != :normal, do: false
# 同花顺比余下都大, 以下类推
def win?({:flush_straight, _}, _), do: true
def win?(_, {:flush_straight, _}), do: false
def win?({:three, _}, _), do: true
def win?(_, {:three, _}), do: false
def win?({:flush, _}, _), do: true
def win?(_, {:flush, _}), do: false
def win?({:straight, _}, _), do: true
def win?(_, {:straight, _}), do: false
# 普通牌需要比较点数
def win?({:normal, p1}, {:normal, p2}), do: p1 > p2 # 赢多少倍
def multiply({:tian_gong, _}), do: 1
def multiply({:flush_straight, _}), do: 16
def multiply({:three, _}), do: 8
def multiply({:flush, _}), do: 4
def multiply({:straight, _}), do: 2
def multiply({:normal, _}), do: 1 def is_flush?([{s, _}, {s, _}, {s, _}]), do: true
def is_flush?(_), do: false def is_straight?([{_, p1}, {_, p2}, {_, p3}]) do
[n1, n2, n3] = [p1, p2, p3] |> Enum.sort
cond do
n1 + 1 == n2 and n2 + 1 == n3 -> true
n1 == @ace and n2 + 1 == n3 -> true
n1 == @ace and n2 + 2 == n3 -> true
true -> false
end
end def is_three?([{_, p}, {_, p}, {_, p}]), do: true
def is_three?([{_, p1}, {_, p2}, {_, p3}]) do
case [p1, p2, p3] |> Enum.sort do
[@ace, @ace, _] -> true
[@ace, n, n] -> true
_other -> false
end
end def is_flush_straight?(cards), do: is_flush?(cards) and is_straight?(cards) end # SimplePoker.init_cards |> SimplePoker.shuffle |> IO.inspect
# SimplePoker.init_cards |> SimplePoker.init_deal(2) |> IO.inspect

simple_poker.ex

测试代码 simple_poker_test.exs

defmodule SimplePokerTest do
use ExUnit.Case
doctest SimplePoker setup do
%{
s_ace: {1,1}, # 黑桃A
h_ace: {2, 1}, # 红桃A,
c_ace: {3, 1}, # 梅花A
s_two: {1, 2}, # 黑桃2
h_two: {2, 2}, # 红桃2
c_two: {3, 2}, # 梅花2
s_three: {1, 3}, # 黑桃3
h_three: {2, 3}, # 红桃3
s_four: {1, 4}, # 黑桃4
h_four: {2, 4}, # 红桃4
s_five: {1, 5}, # 黑桃5
s_eight: {1, 8}, # 黑桃8
s_nine: {1, 9}, # 黑桃9
s_ten: {1, 10}, # 黑桃10
s_jack: {1, 11} }
end test "同花: 黑桃A,黑桃2, 黑桃3 ", cards do
flush_cards = [cards.s_ace, cards.s_two, cards.s_three]
assert SimplePoker.is_flush?(flush_cards)
end test "非同花: 黑桃A, 红桃A, 黑桃2 ", cards do
not_flush_cards = [cards.s_ace, cards.h_ace, cards.s_two]
refute SimplePoker.is_flush?(not_flush_cards)
end test "三条: 普通", cards do
normal_three = [cards.s_two, cards.h_two, cards.c_two]
assert SimplePoker.is_three?(normal_three)
end test "三条:1张A + 1对 ", cards do
one_ace_and_one_pair = [cards.s_two, cards.h_two, cards.s_ace]
assert SimplePoker.is_three?(one_ace_and_one_pair)
end test "三条: 2张A + 1张2 ", cards do
two_ace_and_one = [cards.s_ace, cards.h_ace, cards.s_two]
assert SimplePoker.is_three?(two_ace_and_one)
end test "非三条: A, 2, 3", cards do
not_three = [cards.s_ace, cards.s_two, cards.s_three]
refute SimplePoker.is_three?(not_three)
end test "顺子: 普通 黑桃2, 黑桃3, 红桃4", cards do
normal_straight = [cards.s_two, cards.s_three, cards.h_four]
assert SimplePoker.is_straight?(normal_straight)
end test "顺子: 普通 黑桃A, 黑桃2, 红桃3", cards do
one_ace_normal_straight = [cards.s_ace, cards.s_two, cards.h_three]
assert SimplePoker.is_straight?(one_ace_normal_straight)
end test "顺子: 普通 黑桃A, 黑桃2, 红桃4", cards do
one_ace_normal_straight = [cards.s_ace, cards.s_two, cards.h_four]
assert SimplePoker.is_straight?(one_ace_normal_straight)
end test "非顺子: 黑桃A, 黑桃2, 红桃2", cards do
not_straight = [cards.s_ace, cards.s_two, cards.h_two]
refute SimplePoker.is_straight?(not_straight)
end test "同花顺: 普通", cards do
normal_flush_straight = [cards.s_two, cards.s_three, cards.s_four]
assert SimplePoker.is_flush_straight?(normal_flush_straight)
end test "普通三张", cards do
normal = [cards.s_two, cards.s_two, cards.h_three]
assert {:normal, _} = SimplePoker.power(normal, false)
end test "天公9点", cards do
assert {:tian_gong, 9} = [cards.s_ace, cards.s_eight] |> SimplePoker.power(true)
assert {:tian_gong, 9} = [cards.s_four, cards.s_five] |> SimplePoker.power(true)
end test "普通9点", cards do
assert {:normal, 9} = [cards.s_ace, cards.s_eight] |> SimplePoker.power(false)
end test "single_point", cards do
assert 1 == cards.s_ace |> SimplePoker.single_point
assert 10 == cards.s_ten |> SimplePoker.single_point
assert 10 == cards.s_jack |> SimplePoker.single_point
end test "win?" do
tian_gong_9 = {:tian_gong, 9}
tian_gong_8 = {:tian_gong, 8}
flush_straight = {:flush_straight, 0}
three = {:three, 0}
flush = {:flush, 0}
straight = {:straight, 0}
normal_9 = {:normal, 9}
normal_8 = {:normal, 8} assert SimplePoker.win?(tian_gong_9, tian_gong_8)
refute SimplePoker.win?(tian_gong_9, tian_gong_9)
refute SimplePoker.win?(tian_gong_8, tian_gong_9)
assert SimplePoker.win?(tian_gong_9, flush_straight)
refute SimplePoker.win?(flush_straight, tian_gong_9) refute SimplePoker.win?(flush_straight, flush_straight)
assert SimplePoker.win?(flush_straight, three)
refute SimplePoker.win?(three, flush_straight) assert SimplePoker.win?(three, flush)
refute SimplePoker.win?(flush, three) assert SimplePoker.win?(flush, straight)
refute SimplePoker.win?(straight, flush) assert SimplePoker.win?(straight, normal_9)
refute SimplePoker.win?(normal_9, straight) assert SimplePoker.win?(normal_9, normal_8)
refute SimplePoker.win?(normal_9, normal_9)
refute SimplePoker.win?(normal_8, normal_9)
end end

simple_poker_test.exs

下回该建模游戏桌了

简单Elixir游戏服设计-玩法simple_poker的更多相关文章

  1. 简单Elixir游戏服设计- 游戏玩法介绍

    抄以前的,做了点修改. 到目前为止,我们完成了玩家的数据和进程建模,现在介绍游戏玩法. 为什么我们还不做客户端接入.协议指定呢?为什么还没有网关和数据存储呢.在我接手的游戏, 这些通常已经定下来了,我 ...

  2. 简单Elixir游戏服设计-玩家进程注册

    上回说用Registry 做本地注册(跨服可以用syn,只是稍微麻烦点,需要模拟global注册机制,写个封装模块). 修改game_server 项目的mix.exs, 增加应用启动 def app ...

  3. 简单Elixir游戏服设计-玩家进程跑起来

    有了玩家模型,我们试试让玩家进程跑起来. 需要搞个PlayerSupervisor来负责启动和监控玩家进程. defmodule PlayerSupervisor do use Supervisor ...

  4. 简单Elixir游戏服设计-创建玩家模型

    删除model.ex 创建玩家模型 player.ex, 简单化,只有唯一标识,昵称,金币,够用了. 选择 map 代表数据,是为了扩展数据结构,方便增加功能.struct也是可以的. add_num ...

  5. 简单Elixir游戏服设计- 创建项目

    反正是写到哪算哪. 创建umbrella项目 mix new simple_game --umbrella 创建model项目 cd simple_game\apps mix new model 创建 ...

  6. Elixir游戏服设计五

    在<Elixir游戏服设计一>里提到,按照系统功能划分成app要保证原子性很难, 现在想想也没那么难.保证原子性,无非就是需要某个单点去完成操作.那么选择玩家进程去做原子性工作就可以了. ...

  7. Elixir游戏服设计一

    在Erlang游戏服设计总结http://www.cnblogs.com/rubyist/p/5530575.html里, 我提到我想要的游戏服设计方法,希望以应用做为基础构建块.最近我在学习elix ...

  8. Elixir游戏服设计三

    玩家进程用gen_server来建模,我不直接使用 use GenServer, 而是使用exactor,该库可以去掉反锁的接口定义. 我们新建一个 player_server_manager app ...

  9. 关于Elixir游戏服设计系列

    写着写着就废球了,感觉空对空,实在没什么意思. 另外很快就要搞新项目,决定新项目就直接上elixir了.目前该做的准备工作已经探索了一些了. 以下的东西是写给同事参考的,感兴趣的可以看看,提建议更好. ...

随机推荐

  1. Redis在java中的使用

    1.首先安装Redis环境.可以在Windows.linux.别的服务器上搭建Redis环境 2.在java工程中导入必须的jar包 如maven上导入两个jar] <!-- Redis必须包 ...

  2. Oracle数据库只读事务和无事务的区别

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt382 Oracle默认情况下(没有事务) 保证了SQL语句级别的读一致性,即 ...

  3. ROS学习记录(一)————创建简单的机器人模型smartcar

    这是我在古月居上找的(http://www.guyuehome.com/243),但直接运行的话,没办法跑起来,我也是查了好多博客和日志,才实现最后的功能的,所以,记录下来,以备后用吧,也欢迎其他和我 ...

  4. jQuery === 面条式代码?

    自从React/Vue等框架流行之后,jQuery被打上了面条式代码的标签,甚至成了"过街老鼠",好像谁还在用jQuery,谁就还活在旧时代,很多人都争先恐后地拥抱新框架,各大博客 ...

  5. HTTPS静态服务搭建过程详解

    HTTPS服务对于一个前端开发者来说是一个天天打招呼的老伙计了,但是之前我跟HTTPS打交道的场景一直是抓包,自己没有亲自搭建过HTTPS服务,对HTTPS的底层知识也是一知半解.最近正好遇到一个用户 ...

  6. nrm的安装 、定义和用法

    因为npm包管理工具是属于国外的,所以在中国使用它下载东西的时候比较慢.这时我们就想用国内的淘宝镜像.也有别的,所以当你想切换下载源的时候就会用到nrm了. ###首先,nrm是什么呢? 开发的npm ...

  7. 图论中DFS与BFS的区别、用法、详解…

    DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...

  8. C# 引用类型之特例string

    在C#编程的时候经常会使用字符串(string)类型,它也是引用类型,但是处处都不作为引用的用法来使用,实属特例,下来我一一罗列出来,供自己记忆方便: 1)字符串的直接赋值:本身字符串就是引用类型,应 ...

  9. 团队作业八——第二次团队冲刺(Beta版本)第7天&项目汇总

    项目汇总 第一天:http://www.cnblogs.com/newteam6/p/6879383.html 第二天:http://www.cnblogs.com/newteam6/p/688078 ...

  10. 201521123091 《Java程序设计》第5周学习总结

    Java 第五周总结 第五周的作业. 目录 1.本章学习总结 2.Java Q&A 3.使用码云管理Java代码 4.PTA实验 1.本章学习总结 1.1 尝试使用思维导图总结有关多态与接口的 ...