文档章节

(整理)用Elixir做一个多人扑克游戏 4

ljzn
 ljzn
发布于 2016/10/06 21:59
字数 435
阅读 63
收藏 0
点赞 0
评论 0

sockets 和 channels 是Phoenix中用来实现实时效果的两大工具。

Sockets

socket是用来连接客户端与服务器的,它使用endpoint来声明:

defmodule GenPoker.Endpoint do
  use Phoenix.Endpoint, otp_app: :gen_poker

  socket "/socket", GenPoker.PlayerSocket
end

Channels

客户端只有加入了channel之后才能发送消息。

defmodule GenPoker.PlayerSocket do
  use Phoenix.Socket

  channel "tables:*", GenPoker.TableChannel
end

创建socket

defmodule GenPoker.PlayerSocket do
  use Phoenix.Socket

  transport :websocket, Phoenix.Transports.WebSocket

  def connect(%{"playerId" => player_id}, socket) do
    {:ok, assign(socket, :player_id, player_id)}
  end

  def id(socket) do 
    "players_socket:#{socket.assigns.player_id}"
  end
end

注册进程

defmodule Poker.Table do
  use GenServer

  def start_link(table_name, sup, storage, num_seats) do
    GenServer.start_link(
      __MODULE__, 
      [table_name, sup, storage, num_seats], 
      name: via_tuple(table_name)
    )
  end

  defp via_tuple(table) do 
    {:via, :gproc, {:n, :l, {:table, table}}}
  end

  def whereis(table) do
    :gproc.whereis_name({:n, :l, {:table, table}})
  end
end

我们使用了gproc库来注册进程,这样就可以使用一个term而不仅仅是atom作为名字。让我们来定义Channel:

module GenPoker.TableChannel do
  use GenPoker.Web, :channel
  alias Poker.Table

  def join("tables:" <> table, _payload, socket) do
    {:ok, assign(socket, :table, table)}
  end

  def handle_in(command, payload, socket) 
    when command in ~w(sit leave buy_in cash_out deal) 
  do
    table = Table.whereis(socket.assigns.table)
    arguments = [table, socket.assigns.player_id] ++ payload
    result = apply(Table, String.to_atom(command), arguments)
    if result == :ok do
      broadcast! socket, "update", Table.get_state(table)
    end
    {:reply, result, socket}
  end
end

对于客户端的join请求,我们有不同的回复。在JavaScript中可以这样写:

channel.push("message", arguments)
  .receive("ok", (msg) => console.log("Got OK!"))
  .receive("error", (msg) => console.log("Oops!"))

发送初始的state

def join("tables:" <> table, _payload, socket) do
  state = table |> Table.whereis |> Table.get_state
  push socket, "update", state
  {:ok, assign(socket, :table, table)}
end

使用handle_info

def join("tables:" <> table, _payload, socket) do
  send self, :after_join
  {:ok, assign(socket, :table, table)}
end

def handle_info(:after_join, socket) do
  state = socket.assigns.table |> Table.whereis |> Table.get_state
  push socket, "update", state
  {:noreply, socket}
end

def handle_info(_, socket) do
  {:noreply, socket}
end

拦截消息

def handle_out("update", state, socket) do
  push socket, "update", hide_other_hands(state, socket)
  {:noreply, socket}
end

defp hide_other_hands(state, socket) do
  player_id = socket.assigns.player_id
  hide_hand_if_current_player = fn
    %{id: ^player_id} = player -> player
    player -> Map.delete(player, :hand)
  end

  update_in(state.players, fn players ->
    Enum.map(players, hide_hand_if_current_player)
  end)
end

完整代码

© 著作权归作者所有

共有 人打赏支持
ljzn
粉丝 29
博文 69
码字总数 96245
作品 0
南平
程序员
(整理)用Elixir做一个多人扑克游戏 1

原文 学习一门新的语言或框架,最好的方法就是做一些小项目。Elixir和Phoenix很适合用来做扑克应用。 洗牌 我们要做的是德州扑克,首先,需要牌组: 我们定义了一个能够给出一套洗好了的52张...

ljzn ⋅ 2016/10/03 ⋅ 2

(整理)用Elixir做一个多人扑克游戏 2

原文 现在我们已经做好了牌面大小的比较,游戏的流程,但还没有做玩家登陆,人数限制,甚至没有将奖金发送给赢家。接下来,让我们来完成它们。 玩家需要兑换游戏中的筹码才能开始游戏,在当不...

ljzn ⋅ 2016/10/04 ⋅ 0

(整理)用Elixir做一个多人扑克游戏 3

今天我们将为德州扑克游戏添加故障恢复能力。 OTP为我们准备好了构建容错程序所需要的工具。我们只需要定义正确的behavior 行为。 Supervisor 有了Supervisor,我们就只需要关心当进程崩溃时...

ljzn ⋅ 2016/10/05 ⋅ 0

独家首发 | NIPS 最佳论文视频解读!德州扑克背后的不完全信息博弈

美国时间, 2017 年 12 月 4 日 8:00。 全球机器学习顶级会议 NIPS 在美国长滩开幕了。 本年度 NIPS 将持续一周,你现在才想参加肯定来不及,因为票早就卖光了。 为了让你隔着太平洋都能跟上...

雷锋字幕组 ⋅ 2017/12/05 ⋅ 0

17年的人工智能承包了我们所有的游戏?!

  【IT168 资讯】在20世纪的大部分时间里,国际象棋博弈都是人工智能研究人员的基准。约翰・麦卡锡(John McCarthy)在20世纪50年代早期创造了“人工智能”一词,曾经把国际象棋称为“人工智...

it168网站 ⋅ 01/05 ⋅ 0

(二)深入了解超文本

1.给网页增加超链接需要使用元素,格式类似: 其中,通过href属性指定的“AAAA”为指向的目标文件,"BBBB"为可点击的链接文本。 2.利用属性可以指定元素的附加信息,其写法都是一样的,即属性...

好好先生_1028 ⋅ 2016/06/12 ⋅ 0

(译)循序渐进学习Elixir

——Chris Bell Learning Elixir at Made by Many 在今年奥兰多的Elixir大会上演讲之后,就经常有人问我:你们团队是如何学习Elixir和OTP的? 和学习其他语言一样,学习Elixir也需要付出时间...

ljzn ⋅ 2016/09/29 ⋅ 0

2017败北清单:人工智能在这些游戏中战胜了人类

20世纪90年代后期,IBM深蓝(Deep Blue)研究了一系列的国际象棋算法,期望于打败当时的世界冠军加里•卡斯帕罗夫(Garry Kasparov)。终于,在1997年深蓝成功打败了卡斯帕罗夫,这是历史上计...

技术小能手 ⋅ 01/08 ⋅ 0

Pokerth

PokerTH是一个用C++/QT4写的单用户的扑克游戏。你能和最多六个电脑对手玩流行的"Texas Hold'em"扑克。这个扑克引擎是开源和在Linux, Windows和MacOSX上可用的。 开始网络游戏 网络游戏多达七...

匿名 ⋅ 2008/11/14 ⋅ 1

从不做线上推广,这家棋牌公司用线下比赛月入百万

  近年来,随着移动互联网的兴起和移动支付的普及,棋牌类智力运动的用户量大幅提升。据伽马数据统计,2016年中国棋牌游戏用户规模达到2.58亿,也就是说在中国,平均每5个人中就有一个棋牌...

网狐棋牌开发 ⋅ 2017/11/29 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

idea 整合 vue 启动

刚学习Vue 搭建了一个项目 只能命令启动 Idea里面不会启动 尝试了一下修改启动的配置 如下: 1.首先你要保证你的package.json没有修改过 具体原因没有看 因为我改了这个name的值 就没办法启动...

事儿爹 ⋅ 21分钟前 ⋅ 0

数据仓库技术概述(一看就是架构师写的,对我极其有用)

ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract)、交互转换(transform)、加载(load)至目的端的过程。ETL一词较常用在数据仓库,但其对象并不限于...

gulf ⋅ 23分钟前 ⋅ 0

redis在windows环境的后台运行方法

在后台运行,首先需要安装redis服务,命令为 redis-server.exe --service-install redis.windows.conf --loglevel verbose 启动,命令为 redis-server --service-start 停止,命令为 redis-...

程序羊 ⋅ 24分钟前 ⋅ 0

比特币现金开发者提出新的交易订单规则

本周,四位比特币现金的四位开发者和研究员:Joannes Vermorel(Lokad),AmaurySéchet(比特币ABC),Shammah Chancellor(比特币ABC)和Tomas van der Wansem(Bitcrust)共同发表了一篇关...

lpy411 ⋅ 28分钟前 ⋅ 0

vue获取input输入框的数据

用惯了jQuery,突然使用vue感觉很不习惯,有很多不同的地方,感觉是两个不同的思想来写前端的代码。jQuery是使用选择器($)选取DOM对象,对其进行赋值、取值、事件绑定等操作。而Vue则是通过...

王子城 ⋅ 30分钟前 ⋅ 0

竟然这就是面向对象的游戏设计?!

从程序角度考虑,许多 JavaScript 都基于循环和大量的 if/else 语句。在本文中,我们可了解一种更聪明的做法 — 在 JavaScript 游戏中使用面向对象来设计。本文将概述原型继承和使用 JavaSc...

柳猫 ⋅ 35分钟前 ⋅ 2

git cmd git bash

刚用到了Git,看到windows环境下有两个命令输入窗口 第一个是可视化图形界面,第二个是CMD,第三个是Bash。 Git中的Bash是基于CMD的,在CMD的基础上增添一些新的命令与功能。所以建议在使用的...

东东笔记 ⋅ 37分钟前 ⋅ 0

分布式系统CAP和Base

1、分布式系统 1.1 简介 由多台计算机和通信的软件组件通过计算机网络连接(本地网络或广域网)组成。分布式系统是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的...

xixingzhe ⋅ 48分钟前 ⋅ 0

查看磁盘占用情况

记一次jenkins构建失败的问题 Build step 'Send build artifacts over SSH' changed build result to UNSTABLE 网上查资料都没明确表明是什么错,回忆之前处理这样的问题。第一时间想到的是不...

ManderSF ⋅ 50分钟前 ⋅ 0

数据库管理提速:SQL解析的探索与应用

前言: SQL解析是一项复杂的技术,一般都是由数据库厂商来掌握,当然也有公司专门提供SQL解析的API。SQL解析与优化是属于编译器范畴,和C语言等其他语言的解析没有本质的区别。其中分为词法分...

java高级架构牛人 ⋅ 57分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部