constant W = 60, H = 30, MAX_LEN = 600 enum NORTH, EAST, SOUTH, WEST sequence board, snake bool alive integer tailIdx, headIdx, hdX, hdY, d, points procedure createField() clear_screen() board = repeat("+"&repeat(' ',W-2)&'+',H) for x=1 to W do board[1,x] = '+' end for board[H] = board[1] board[1+rand(H-2),1+rand(W-2)] = '@'; snake = repeat(0,MAX_LEN) board[3,4] = '#'; tailIdx = 1; headIdx = 5; for c=tailIdx to headIdx do snake[c] = {3,3+c} end for {hdY,hdX} = snake[headIdx-1]; d = EAST; points = 0; end procedure procedure drawField() for y=1 to H do for x=1 to W do integer t = board[y,x] if t!=' ' then position(y,x) if x=hdX and y=hdY then text_color(14); puts(1,'O'); else text_color({10,9,12}[find(t,"#+@")]); puts(1,t); end if end if end for end for position(H+1,1); text_color(7); printf(1,"Points: %d",points) end procedure procedure readKey() integer k = find(get_key(),{333,331,328,336}) if k then d = {EAST,WEST,NORTH,SOUTH}[k] end if end procedure procedure moveSnake() integer x,y switch d do case NORTH: hdY -= 1 case EAST: hdX += 1 case SOUTH: hdY += 1 case WEST: hdX -= 1 end switch integer t = board[hdY,hdX]; if t!=' ' and t!='@' then alive = false; return; end if board[hdY,hdX] = '#'; snake[headIdx] = {hdY,hdX}; headIdx += 1; if headIdx>MAX_LEN then headIdx = 1 end if if t=='@' then points += 1 while 1 do x = 1+rand(W-2); y = 1+rand(H-2); if board[y,x]=' ' then board[y,x] = '@' return end if end while end if {y,x} = snake[tailIdx]; position(y,x); puts(1,' '); board[y,x] = ' '; tailIdx += 1; if tailIdx>MAX_LEN then tailIdx = 1 end if end procedure procedure play() while true do createField(); alive = true; cursor(NO_CURSOR) while alive do drawField(); readKey(); moveSnake(); sleep(0.05) end while cursor(BLOCK_CURSOR); position(H+2,1); bk_color(0); text_color(11); puts(1,"Play again [Y/N]? ") if upper(wait_key())!='Y' then return end if end while end procedure play()