############################################################################ # # File: tron.icn # # Subject: Program to play a Tron-like video game # # Author: Eduardo Ochs # # Date: November 18, 2009 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # Rules: You're yellow, and you leave a yellow trail when you walk. # You never stop until you die. You die when you hit something # yellow. Use the arrow keys to change your direction. Try to make # the best score you can before you die. You only live once. # # In the beginning it's a black arena with yellow walls and a red # 3x3 pixel square somewhere. Walking over a red pixel gives you # one point and makes another 3x3 square appear somewhere. So, # crossing a 3x3 red square from one side to another gives you # three points and makes three other squares appear in random # positions. # # Walking over black pixels is harmless. # # Sometimes the red squares will appear over your trail. Then some # pixels of your trail will become red and you'll be able to cross. # # The game loop and the outer loop: typing "Q" or Esc or losing when # you're playing makes you go to the outer loop; in the outer loop # typing "P" or Enter or space restarts the game, and typing "Q" or # Esc leaves the program. # # Source: # Htmlized: # Screenshot: # See also: # # ############################################################################ # # Requires: Version 9 graphics # ############################################################################ # # Links: graphics, random # ############################################################################ link graphics link random $include "keysyms.icn" global actions, direction global x, y, dx, dy global score global pixels procedure prepare_vars() actions := table() actions[Key_Down] := ["v", +1] actions[Key_Up] := ["v", -1] actions[Key_Right] := ["h", +1] actions[Key_Left] := ["h", -1] every actions["q" | "Q" | "\e"] := "quit" set_direction(["h", +1]) x := 150 y := 90 score := 0 pixels := table() every pixels[0 to 199] := table(0) end procedure set_color(n) if n == 0 then WAttrib("fg=black") if n == 1 then WAttrib("fg=red") if n == 3 then WAttrib("fg=yellow") end procedure pset(x, y, color) set_color(color) pixels[y][x] := color FillRectangle(x*2, y*2, 2, 2) end procedure point(x, y) return pixels[y][x] end procedure draw_red_square() local x, y x := ?316 y := ?188 every pset(x to x+2, y to y+2, 1) end procedure is_direction(action) return type(action) == "list" end procedure ignored_turn(newdirection) return newdirection[1] == direction[1] end procedure set_direction(newdirection) direction := newdirection if direction[1] == "h" then { dx := direction[2]; dy := 0 } else { dy := direction[2]; dx := 0 } end procedure process_events() local e, action while *Pending() > 0 do { e := Event() # w(e) action := actions[e] if is_direction(action) then { if not ignored_turn(action) then { set_direction(action) return } } if action === "quit" then fail } return end procedure prepare_walls() every pset(0 to 319, 0, 3) every pset(0 to 319, 191, 3) every pset(0, 0 to 191, 3) every pset(319, 0 to 191, 3) end procedure draw_score() GotoXY(6, 396) set_color(3) WWrites("Score: " || score) end procedure play() prepare_vars() set_color(0) FillRectangle(0, 0, 640, 400) prepare_walls() pset(x, y, 3) draw_red_square() draw_score() WDelay(1000) while process_events() do { x +:= dx y +:= dy if point(x, y) == 3 then break if point(x, y) == 1 then { draw_red_square(); score +:= 1; draw_score() pset(x, y, 3) WDelay(50) } pset(x, y, 3) WDelay(50) } end procedure main(args) local e # w(actions) WOpen("size=640,400", "fg=yellow", "bg=black") WAttrib("font=Helvetica,12,bold") randomize() while 1 do { play() while e := Event() do { if e === ("q" | "Q" | "\e") then return if e === ("p" | "P" | " " | "\r" | "\n") then break } } end