diff --git a/src/default.opa b/src/default.opa index 65b09c2..c418ea2 100644 --- a/src/default.opa +++ b/src/default.opa @@ -54,8 +54,25 @@ Default = {{ grid, Set.empty:set(Base.pos)) food = get_grid_nums(1) + walls = get_grid_nums(8) + teleports = + elts = + get_grid_nums(5) + |> Set.fold( + ~{x y}, acc -> [{line=y}|[{column=x}|acc]], + _, []) + |> List.sort + if elts == [] then [] + else + List.fold( + e, (prev, acc) -> + if e == prev then (e, [e|acc]) + else (e, acc), + List.tail(elts), (List.head(elts), [])) + |> _.f2 + pacman = { base = Base.make(0, 0, {right}, 10) next_dir = {right} diff --git a/src/ghost.opa b/src/ghost.opa index d1c3f5c..091ed70 100644 --- a/src/ghost.opa +++ b/src/ghost.opa @@ -34,13 +34,13 @@ @private build_move_options(b:Base.t, no_back) = all_options = [] : list(Base.direction) - |> (if Wall.at(b.pos.x+1, b.pos.y) then identity + |> (if Wall.at(b.pos.x+1, b.pos.y, false) then identity else List.add({right}, _)) - |> (if Wall.at(b.pos.x-1, b.pos.y) then identity + |> (if Wall.at(b.pos.x-1, b.pos.y, false) then identity else List.add({left}, _)) - |> (if Wall.at(b.pos.x, b.pos.y+1) then identity + |> (if Wall.at(b.pos.x, b.pos.y+1, false) then identity else List.add({down}, _)) - |> (if Wall.at(b.pos.x, b.pos.y-1) then identity + |> (if Wall.at(b.pos.x, b.pos.y-1, false) then identity else List.add({up}, _)) if List.length(all_options) == 1 then all_options else if no_back then diff --git a/src/pacman.opa b/src/pacman.opa index 5db39ab..155b4c0 100644 --- a/src/pacman.opa +++ b/src/pacman.opa @@ -1,7 +1,6 @@ @client Pacman = {{ - draw(g, ctx:Canvas.context) = - p = g.pacman + @private draw_one(p:Pacman.t, ctx:Canvas.context) = w = base_size mouth = p.mouth_step @@ -31,6 +30,28 @@ do Canvas.restore(ctx) void + @private draw_clones(f:Base.pos->Base.pos, p1:Pacman.t, ctx:Canvas.context) = + p2 = {p1 with base={p1.base with pos=f(p1.base.pos)}} + do draw_one(p1, ctx) + do draw_one(p2, ctx) + void + + draw(g, ctx:Canvas.context) = + p = g.pacman + if (p.base.dir == {left} || p.base.dir == {right}) + && p.base.pos.x == 0 then + draw_clones({x=_ ~y} -> {x=grid_width ~y}, p, ctx) + else if (p.base.dir == {left} || p.base.dir == {right}) + && p.base.pos.x == grid_width-1 then + draw_clones({x=_ ~y} -> {x=-1 ~y}, p, ctx) + else if (p.base.dir == {up} || p.base.dir == {down}) + && p.base.pos.y == 0 then + draw_clones({~x y=_} -> {~x y=grid_heigth}, p, ctx) + else if (p.base.dir == {up} || p.base.dir == {down}) + && p.base.pos.y == grid_heigth-1 then + draw_clones({~x y=_} -> {~x y=-1}, p, ctx) + else draw_one(p, ctx) + move(g) = p = g.pacman ignore_incr = p.base.cur_step < 0 @@ -39,7 +60,7 @@ else if Base.Dir.is_still(p.base.dir) then 0 else cur_step test_wall(on_ok, on_err, x, y) = - if Wall.at(x,y) then on_err + if Wall.at(x,y, true) then on_err else on_ok (dir, dx, dy) = if cur_step != 0 then (p.base.dir, 0, 0) @@ -55,8 +76,8 @@ if ignore_incr then (dir, 0, 0) else (dir, dx, dy) pos = { - x = p.base.pos.x + dx - y = p.base.pos.y + dy + x = mod(grid_width + p.base.pos.x + dx, grid_width) + y = mod(grid_heigth + p.base.pos.y + dy, grid_heigth) } (food, score) = diff --git a/src/types.opa b/src/types.opa index 02f6247..ed6dcdd 100644 --- a/src/types.opa +++ b/src/types.opa @@ -8,6 +8,10 @@ type Base.pos = { y : int } +type Base.teleports = + { line : int } + / { column : int } + type Base.t = { pos : Base.pos dir : Base.direction diff --git a/src/wall.opa b/src/wall.opa index aed7901..efb43dc 100644 --- a/src/wall.opa +++ b/src/wall.opa @@ -10,9 +10,16 @@ do Canvas.restore(ctx) void - at(x, y) = - x >= grid_width || y >= grid_heigth - || x < 0 || y < 0 - || Set.mem(~{x y}, Default.walls) + at(x, y, may_teleport) = + border = + if may_teleport then + if x < 0 || x >= grid_width then + not(List.mem({line=y}, Default.teleports)) + else if y < 0 || y >= grid_width then + not(List.mem({column=x}, Default.teleports)) + else false + else + x >= grid_width || y >= grid_heigth || x < 0 || y < 0 + border || Set.mem(~{x y}, Default.walls) }}