今天本来想说点 rust 的, 但时间不够了. 这几天初学 rust, 很是喜欢, 但有一点, yu才不会用 rust 写并发程序. 今天就玩 phoenix 吧. 其实yu不是很喜欢这种 web 框架, 把前后端的代码都放在一起的做法. 正经做事的时候, 前后端都是分开的. 但 phoenix 对于前端或者后端程序员来说, 都是一个很好的玩具, 帮你慢慢了解你所不懂的那部分技术.
其实呢, yu很喜欢玩扑克牌, 各种类型的都玩, 那就做个扑克类游戏吧, 用phoenix.
资源
然而, yu并没有扑克牌的图片资源, 也懒得去找了, 然而扑克是世界的, 大佬们早已在 Unicode 字符集里为yu提供了全套的扑克牌.
那就做个 elixir 数据结构与 unicode 扑克字符的 parser吧:
defmodule Unipoke do
@moduledoc """
unicode字符与 扑克牌数据 相互转换.
"""
@doc """
card to unicode.
"""
def encode({r, s}) when is_atom(s), do: encode {s, r}
def encode({:spades, 14}), do: <<240,159,130,161>>
def encode({:spades, r}) when r in 2..13 do
<<240,159,130,160+r>>
end
def encode({:hearts, 14}), do: <<240,159,130,177>>
def encode({:hearts, r}) when r in 2..13 do
<<240,159,130,176+r>>
end
def encode({:diamonds, 14}), do: <<240,159,131,129>>
def encode({:diamonds, r}) when r in 2..13 do
<<240,159,131,128+r>>
end
def encode({:clubs, 14}), do: <<240,159,131,145>>
def encode({:clubs, r}) when r in 2..13 do
<<240,159,131,144+r>>
end
end
这里是 encode, 你可以在 iex 里面试一下, 就能看到扑克牌啦. decode 这里就不占篇幅了(其实是还没写).
显示
资源问题解决了, 怎么显示到网页上. 而且, 每张牌需要可以点击.
在 phoenix 里, 我们写的不是普通的html, 而是 html.eex, yu感觉这很像 macro, 先编译, 再运行. 所以, 可以在编译 eex时用 elixir 代码生成扑克牌的按钮.
有 phoenix 帮忙, yu就不用写 js 了. 在新建的 phoenix 项目的 page/index.html.eex
里面, 加上这一段:
<div>
<%= render_existing(@view_module, "cards." <> @view_template, assigns) %>
<div>
page 里所有eex都公用一个专属的parser, 也就是 PageView
模块.
defmodule Unipoke.Web.PageView do
use Unipoke.Web, :view
def render("cards.index.html", _) do
{:safe,
Deck.ordered
|> Enum.map(&Unipoke.encode/1)
|> Enum.map(fn x -> "<button class=\"card\">" <> x <> "</button>" end)
|> Enum.chunk(13)
|> Enum.map(fn x -> x ++ ["<br/>"] end)
|> List.flatten()
|> Enum.join()
}
end
end
Deck 模块就是生成牌堆啦.
def ordered, do: for suit <- suits(), rank <- ranks(), do: {rank, suit}
defp ranks, do: Enum.to_list(2..14)
defp suits, do: [:spades, :clubs, :hearts, :diamonds]
好了, 打开网页看下
好他喵丑噢. 而且 C 是什么鬼啊