Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
266
Task/2048/Pony/2048.pony
Normal file
266
Task/2048/Pony/2048.pony
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
use "term"
|
||||
use "random"
|
||||
use "time"
|
||||
|
||||
interface EdgeRow
|
||||
fun val row() : Iterator[U32] ref
|
||||
fun val inc() : I32
|
||||
|
||||
primitive TopRow is EdgeRow
|
||||
fun row() : Iterator[U32] ref => let r : Array[U32] box = [0,1,2,3]
|
||||
r.values()
|
||||
fun inc() : I32 => 4
|
||||
|
||||
primitive LeftRow is EdgeRow
|
||||
fun row() : Iterator[U32] ref => let r : Array[U32] box = [0,4,8,12]
|
||||
r.values()
|
||||
fun inc() : I32 => 1
|
||||
|
||||
primitive RightRow is EdgeRow
|
||||
fun row() : Iterator[U32] ref => let r : Array[U32] box = [3,7,11,15]
|
||||
r.values()
|
||||
fun inc() : I32 => -1
|
||||
|
||||
primitive BottomRow is EdgeRow
|
||||
fun row() : Iterator[U32] ref => let r : Array[U32] box = [12,13,14,15]
|
||||
r.values()
|
||||
fun inc() : I32 => -4
|
||||
|
||||
primitive LEFT
|
||||
primitive RIGHT
|
||||
primitive UP
|
||||
primitive DOWN
|
||||
type Move is (LEFT|RIGHT|UP|DOWN)
|
||||
|
||||
class KeyboardHandler is ANSINotify
|
||||
let _game : Game tag
|
||||
new iso create(game : Game tag) => _game = game
|
||||
|
||||
fun ref apply(term: ANSITerm ref, input: U8 val) =>
|
||||
if input == 113 then
|
||||
_game.quit()
|
||||
term.dispose()
|
||||
end
|
||||
fun ref left(ctrl: Bool, alt: Bool, shift: Bool) => _game.move(LEFT)
|
||||
fun ref down(ctrl: Bool, alt: Bool, shift: Bool) => _game.move(DOWN)
|
||||
fun ref up(ctrl: Bool, alt: Bool, shift: Bool) => _game.move(UP)
|
||||
fun ref right(ctrl: Bool, alt: Bool, shift: Bool) => _game.move(RIGHT)
|
||||
|
||||
type ROW is (U32,U32,U32,U32)
|
||||
|
||||
primitive Merger
|
||||
fun tag apply(r : ROW) : ROW =>
|
||||
match r
|
||||
| (0,0,0,_) => (r._4,0,0,0)
|
||||
| (0,0,_,r._3) => (r._3<<1,0,0,0)
|
||||
| (0,0,_,_) => (r._3,r._4,0,0)
|
||||
| (0,_,r._2,_) => (r._2<<1,r._4,0,0)
|
||||
| (0,_,0,r._2) => (r._2<<1,0,0,0)
|
||||
| (0,_,0,_) => (r._2,r._4,0,0)
|
||||
| (0,_,_,r._3) => (r._2,r._3<<1,0,0)
|
||||
| (0,_,_,_) => (r._2,r._3,r._4,0)
|
||||
| (_, r._1, _, r._3) => (r._1<<1, r._3<<1, 0, 0)
|
||||
| (_, r._1, 0, _) => (r._1<<1, r._4, 0, 0)
|
||||
| (_, r._1, _, _) => (r._1<<1, r._3, r._4, 0)
|
||||
| (_, 0,r._1, _) => (r._1<<1,r._4,0,0)
|
||||
| (_, 0,0, r._1) => (r._1<<1,0,0,0)
|
||||
| (_, 0,0, _) => (r._1,r._4,0,0)
|
||||
| (_, 0,_, r._3) => (r._1, r._3<<1,0,0)
|
||||
| (_, 0,_, _) => (r._1, r._3,r._4,0)
|
||||
| (_,_,r._2,_) => (r._1, r._2<<1,r._4,0)
|
||||
| (_,_,0,r._2) => (r._1, r._2<<1,0,0)
|
||||
| (_,_,0,_) => (r._1, r._2,r._4,0)
|
||||
| (_,_,_,r._3) => (r._1, r._2,r._3<<1,0)
|
||||
else
|
||||
r
|
||||
end
|
||||
/**
|
||||
* Game actor
|
||||
*/
|
||||
actor Game
|
||||
embed _grid : Array[U32] = Array[U32].init(0, 16)
|
||||
let _rand : Random = MT(Time.millis())
|
||||
let _env : Env
|
||||
let _board : String ref = recover String(1024) end
|
||||
|
||||
new create(env: Env)=>
|
||||
_env = env
|
||||
_add_block()
|
||||
_add_block()
|
||||
_draw()
|
||||
|
||||
fun _merge(start : U32, inc : I32) : (ROW | None) =>
|
||||
var st = start.i32()
|
||||
let rval : ROW = (_get(st), _get(st + inc),
|
||||
_get(st + (inc * 2)), _get(st + (inc * 3)))
|
||||
let rout = Merger(rval)
|
||||
if rout is rval then None else rout end
|
||||
|
||||
fun ref _update(start : U32, inc : I32) : Bool =>
|
||||
match _merge(start, inc)
|
||||
| let rout : ROW =>
|
||||
var st = start.i32()
|
||||
_set(st, rout._1)
|
||||
_set(st + inc, rout._2)
|
||||
_set(st + (inc * 2), rout._3)
|
||||
_set(st + (inc * 3), rout._4)
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
|
||||
fun ref _shift_to(edge : EdgeRow val) : Bool =>
|
||||
var updated = false
|
||||
for r in edge.row() do
|
||||
if _update(r, edge.inc()) then
|
||||
updated = true
|
||||
end
|
||||
end
|
||||
updated
|
||||
|
||||
fun _fmt(i : U32) : String =>
|
||||
match i
|
||||
| 0 => " __ "
|
||||
| 2 => "\x1B[31m 2 \x1B[0m"
|
||||
| 4 => "\x1B[32m 4 \x1B[0m"
|
||||
| 8 => "\x1B[33m 8 \x1B[0m"
|
||||
| 16 => "\x1B[34m 16 \x1B[0m"
|
||||
| 32 => "\x1B[35m 32 \x1B[0m"
|
||||
| 64 => "\x1B[36m 64 \x1B[0m"
|
||||
| 128 => "\x1B[37m128 \x1B[0m"
|
||||
| 256 => "\x1B[41m\x1B[37m256 \x1B[0m"
|
||||
| 512 => "\x1B[42m\x1B[37m512 \x1B[0m"
|
||||
| 1024 => "\x1B[43m\x1B[37m1024\x1B[0m"
|
||||
| 2048 => "\x1B[47m\x1B[35m\x1B[1m\x1B[5m2048\x1B[0m"
|
||||
else
|
||||
i.string()
|
||||
end
|
||||
|
||||
fun ref _draw() =>
|
||||
let s : String ref = _board
|
||||
s.truncate(0)
|
||||
var i : U32 = 0
|
||||
repeat
|
||||
if (i % 4) == 0 then
|
||||
s.append("---------------------\n")
|
||||
end
|
||||
s.append(_fmt(_get(i)))
|
||||
s.append(" ")
|
||||
i = i + 1
|
||||
if (i % 4) == 0 then
|
||||
s.append("\n")
|
||||
end
|
||||
until i==16 end
|
||||
_env.out.print(s.string())
|
||||
_env.out.print("Arrow keys to move. Press (q)uit key to quit.")
|
||||
|
||||
fun ref _set(i:(I32|U32), v : U32) =>
|
||||
try
|
||||
_grid.update(i.usize(),v)
|
||||
else
|
||||
_env.out.print("cant update!")
|
||||
end
|
||||
|
||||
fun _count() : U64 =>
|
||||
var c : U64 = 0
|
||||
for v in _grid.values() do
|
||||
c = c + if v == 0 then 0 else 1 end
|
||||
end
|
||||
c
|
||||
|
||||
fun ref _add_block() =>
|
||||
let c = _count()
|
||||
if c == 16 then return end
|
||||
|
||||
var hit = _rand.int(16 - c)
|
||||
var i : U32 = 0
|
||||
while i < 16 do
|
||||
if (_get(i) == 0) then
|
||||
if hit == 0 then
|
||||
_set(i, if _rand.int(10) > 0 then 2 else 4 end)
|
||||
break
|
||||
end
|
||||
hit = hit - 1
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
fun _get(i : (I32|U32)) : U32 => try _grid(i.usize()) else 0 end
|
||||
|
||||
fun _win() : Bool =>
|
||||
for v in _grid.values() do
|
||||
if v == 2048 then return true end
|
||||
end
|
||||
false
|
||||
|
||||
fun _no_moves(edge : EdgeRow val) : Bool =>
|
||||
for r in edge.row() do
|
||||
match _merge(r, edge.inc())
|
||||
| let rout : ROW =>
|
||||
if (rout._1 == 0) or (rout._2 == 0) or
|
||||
(rout._3 == 0) or (rout._4 == 0) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
true
|
||||
|
||||
fun _lose() : Bool =>
|
||||
(_grid.size() >= 16) and
|
||||
_no_moves(LeftRow) and
|
||||
_no_moves(RightRow) and
|
||||
_no_moves(TopRow) and
|
||||
_no_moves(BottomRow)
|
||||
|
||||
be quit()=>
|
||||
_env.out.print("Exiting.. some terminals may require <ctrl-c>")
|
||||
_env.exitcode(0)
|
||||
_env.input.dispose()
|
||||
|
||||
be move(m: Move) =>
|
||||
let updated =
|
||||
match m
|
||||
| LEFT => _shift_to(LeftRow)
|
||||
| RIGHT => _shift_to(RightRow)
|
||||
| UP => _shift_to(TopRow)
|
||||
| DOWN => _shift_to(BottomRow)
|
||||
else
|
||||
false
|
||||
end
|
||||
|
||||
if _win() then
|
||||
_draw()
|
||||
_env.out.print("You win :)")
|
||||
quit()
|
||||
else
|
||||
if updated then
|
||||
_add_block()
|
||||
_draw()
|
||||
end
|
||||
if _lose() then
|
||||
_env.out.print("You lose :(")
|
||||
quit()
|
||||
end
|
||||
end
|
||||
|
||||
actor Main
|
||||
new create(env: Env) =>
|
||||
// unit test
|
||||
ifdef "test" then
|
||||
TestMain(env)
|
||||
return
|
||||
end
|
||||
// else game
|
||||
let input : Stdin tag = env.input
|
||||
env.out.print("Welcome to ponylang-2048...")
|
||||
let game = Game(env)
|
||||
let term = ANSITerm(KeyboardHandler(game), input)
|
||||
|
||||
let notify : StdinNotify iso = object iso
|
||||
let term: ANSITerm = term
|
||||
let _in: Stdin tag = input
|
||||
fun ref apply(data: Array[U8] iso) => term(consume data)
|
||||
fun ref dispose() => _in.dispose()
|
||||
end
|
||||
|
||||
input(consume notify)
|
||||
Loading…
Add table
Add a link
Reference in a new issue