简单Elixir游戏服设计-玩法simple_poker

来源:互联网 时间:2017-10-11

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

做到现在感觉目前还没有使用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

 

相关阅读:
Top