Snake: Difference between revisions
Content deleted Content added
Alpha bravo (talk | contribs) Added AutoHotkey |
|||
Line 1,796: | Line 1,796: | ||
Similar to C++ entry |
Similar to C++ entry |
||
</pre> |
</pre> |
||
=={{header|Nim}}== |
|||
{{trans|C}} |
|||
{{libheader|nim-ncurses}} |
|||
As in the C version, the code is provided for Linux. We use the tiny API defined in the C version, only adjusted to work with Nim and the library “nim-ncurses”. |
|||
<lang Nim>import macros, os, random |
|||
import ncurses |
|||
when defined(Linux): |
|||
proc positional_putch(x, y: int; ch: char) = mvaddch(x.cint, y.cint, ch.chtype) |
|||
proc updateScreen = refresh() |
|||
proc nonBlockingGetch(): char = |
|||
let c = getch() |
|||
result = if c in 0..255: char(c) else: '\0' |
|||
proc closeScreen = endwin() |
|||
else: |
|||
error "Not implemented" |
|||
const |
|||
W = 80 |
|||
H = 40 |
|||
Space = 0 |
|||
Food = 1 |
|||
Border = 2 |
|||
Symbol = [' ', '@', '.'] |
|||
type |
|||
Dir {.pure.} = enum North, East, South, West |
|||
Game = object |
|||
board: array[W * H, int] |
|||
head: int |
|||
dir: Dir |
|||
quit: bool |
|||
proc age(game: var Game) = |
|||
## Reduce a time-to-live, effectively erasing the tail. |
|||
for i in 0..<W*H: |
|||
if game.board[i] < 0: inc game.board[i] |
|||
proc plant(game: var Game) = |
|||
## Put a piece of food at random empty position. |
|||
var r: int |
|||
while true: |
|||
r = rand(W * H - 1) |
|||
if game.board[r] == Space: break |
|||
game.board[r] = Food |
|||
proc start(game: var Game) = |
|||
## Initialize the board, plant a very first food item. |
|||
for i in 0..<W: |
|||
game.board[i] = Border |
|||
game.board[i + (H - 1) * W] = Border |
|||
for i in 0..<H: |
|||
game.board[i * W] = Border |
|||
game.board[i * W + W - 1] = Border |
|||
game.head = W * (H - 1 - (H and 1)) shr 1 # Screen center for any H. |
|||
game.board[game.head] = -5 |
|||
game.dir = North |
|||
game.quit = false |
|||
game.plant() |
|||
proc step(game: var Game) = |
|||
let len = game.board[game.head] |
|||
case game.dir |
|||
of North: dec game.head, W |
|||
of South: inc game.head, W |
|||
of West: dec game.head |
|||
of East: inc game.head |
|||
case game.board[game.head] |
|||
of Space: |
|||
game.board[game.head] = len - 1 # Keep in mind "len" is negative. |
|||
game.age() |
|||
of Food: |
|||
game.board[game.head] = len - 1 |
|||
game.plant() |
|||
else: |
|||
game.quit = true |
|||
proc show(game: Game) = |
|||
for i in 0..<W*H: |
|||
positionalPutch(i div W, i mod W, if game.board[i] < 0: '#' else: Symbol[game.board[i]]) |
|||
updateScreen() |
|||
var game: Game |
|||
randomize() |
|||
let win = initscr() |
|||
cbreak() # Make sure thre is no buffering. |
|||
noecho() # Suppress echoing of characters. |
|||
nodelay(win, true) # Non-blocking mode. |
|||
game.start() |
|||
while not game.quit: |
|||
game.show() |
|||
case nonBlockingGetch() |
|||
of 'i': game.dir = North |
|||
of 'j': game.dir = West |
|||
of 'k': game.dir = South |
|||
of 'l': game.dir = East |
|||
of 'q': game.quit = true |
|||
else: discard |
|||
game.step() |
|||
os.sleep(300) # Adjust here: 100 is very fast. |
|||
sleep(1000) |
|||
closeScreen()</lang> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |