LINUX.ORG.RU

История изменений

Исправление MOPKOBKA, (текущая версия) :

Вот консольный Pong, в 186 строк, без определения системных констант и сисколов будет где то 150 строк. Есть простой AI, работает на любом разрешении экрана, можно выбрать пункт игры без AI с другом. Игра идет до 10, потом показывает кто выиграл.

0x5413 constant TIOCGWINSZ
0x5401 constant TCGETS  
0x5404 constant TCSETSF
10 constant ECHO
1 constant POOLIN
: ioctl 3 16 syscall ;
: nanosleep 2 35 syscall ;
: pool 3 7 syscall ;
: 1ms 0 pad ! 1000000 pad cell+ ! pad 0 nanosleep drop ;
: ms for 1ms next ;
: -1/1 -? if 1 else -1 then ;
: xxyy ( x y x y -- x x y y ) rot swap ;

here constant termio 64 allot
1 TCGETS termio ioctl drop 
termio 12 + dup l@ ECHO not and swap l!
1 TCSETSF termio ioctl drop 
27 emit ." [?25l"
27 emit ." [H" 27 emit ." [J"

: quit 
  27 emit ." [?25h"
  termio 12 + dup l@ ECHO or swap l!
  1 TCSETSF termio ioctl drop 
  bye ;

1 TIOCGWINSZ pad ioctl drop
pad w@         constant height 
pad word+ w@   constant width
width height * constant size 
here           constant screen size allot
0   constant  MENU
1   constant  COMPUTER
2   constant  FRIEND
3   constant  WIN
0   variable  mode
0   variable  cursor
9   variable  player1
9   variable  player2
0   variable  score1
0   variable  score2
0 0 variable2 velocity
0 0 variable2 ball

: new-round
  score1 @ 10 >= 
  score2 @ 10 >= 
  or if WIN mode ! then
  score1 @ score2 @ > if -1 else 1 then 
  -1 velocity !2 
  width 2 / height 2 / ball !2 ;

: new-game
  0 score1 !
  0 score2 !
  new-round ;

: target ( -- x y ) ball @2 velocity @2 xxyy + -rot + swap ;  
: flight target ball !2 ;
: collision? ( y -- f ) dup height >= swap 0 < or ;
: rebound ( -- ) velocity @2 negate velocity !2 ;

: walls 
  target swap drop 
  collision? if rebound then ;

: racket-x? ( x px -- f ) if width >= else 0 <= then ;
: racket-y? ( y py -- f ) 2 + - abs 2 <= ;
: racket? ( x y px py -- f ) xxyy racket-y? -rot racket-x? and ;
: power* ( n -- n ) player1 @ player2 @ + 4 mod 1 max * -3 max 3 min ;
: hit velocity @2 swap power* negate swap velocity !2 ;

: players 
  target 0 player1 @ racket? 
  target 1 player2 @ racket? 
  or if hit then ; 
  
: check-goal 
  target drop dup 
  width >= if drop 1 score1 !+ new-round leave then 
  0 <= if 1 score2 !+ new-round then ;

: physics walls players check-goal flight ;

: key ( -- n )
  0 pad
  pad long+ POOLIN swap w!
  pad 1 0 pool drop
  pad long+ word+ w@ POOLIN and if 
    0 pad 100 accept drop pad c@
  else 0 then ;

: moving ( n player -- ) dup @ rot + 0 max height 4 - min swap ! ;

: input 
  key 
  [char] q case -3 player1 moving end
  [char] a case 3 player1 moving end
  [char] p case -3 player2 moving end
  [char] l case 3 player2 moving end
  [char] e case quit end
  drop ;

: visible? 
  velocity @ 0 >
  ball @ width 2 / > and 
  mode @ COMPUTER = and ;
  
: ai 
  visible? if 
    ball cell+ @ player2 @ - negate 
    -1/1 player2 moving 
  then ;

: clear screen size 32 fill ;
: flush screen size .s ;
: point ( x y c -- ) -rot width * + screen + c! ;
: draw-ball ball @2 [char] @ point ;

: draw-player ( x y -- ) 
  4 for 
    dup2 [char] # point 1+ 
  next drop2 ;

: draw-players 
  0 player1 @ draw-player 
  width 1- player2 @ draw-player ;

: draw-border 
  width 2 / 0 height for 
    dup2 [char] | point 1+ 
  next drop2 ;

: draw-score ( score x -- ) 
  3 width * + screen + swap <# #u #> rot swap move ;

: draw-scores 
  score1 @ width 2 / 7 - draw-score 
  score2 @ width 2 / 7 + draw-score ;

: draw draw-border draw-scores draw-ball draw-players ;

: label ( str u )
  dup 2 / width 2 / swap -
  cursor @ width * + screen + swap move
  1 cursor !+ ;

: win 
  height 2 / 4 - cursor !
  score1 @ score2 @ > if
    " Player1 WIN!"
  else
    " Player2 WIN!"
  then
  label
  " Press C to continue" label
  key 
  [char] c case 0 mode ! end
  [char] e case quit end
  drop ;

: menu 
  height 2 / 4 - cursor !
  " PONG" label
  " Q - Player 1 Up, A - Player 1 Down" label
  " P - Player 2 Up, L - Player 2 Down" label
  " E - Exit" label
  " " label
  " " label
  " 1. Play with computer" label
  " 2. Play with friend" label
  key 
  [char] 1 case new-game COMPUTER mode ! end
  [char] 2 case new-game FRIEND mode ! end
  [char] e case quit end
  drop ;
 
: game input ai physics draw ;

: pong 
  @:> clear mode @
    dup MENU = if menu then
    dup dup COMPUTER = swap FRIEND = or if game then
    WIN = if win then
    60 ms
  flush <@ ; pong

Исходная версия MOPKOBKA, :

Вот консольный Pong, в 186 строк, без определения системных констант и сисколов будет где то 150 строк. Есть простой AI, работает на любом разрешении экрана, можно выбрать пункт игры без AI с другом.

0x5413 constant TIOCGWINSZ
0x5401 constant TCGETS  
0x5404 constant TCSETSF
10 constant ECHO
1 constant POOLIN
: ioctl 3 16 syscall ;
: nanosleep 2 35 syscall ;
: pool 3 7 syscall ;
: 1ms 0 pad ! 1000000 pad cell+ ! pad 0 nanosleep drop ;
: ms for 1ms next ;
: -1/1 -? if 1 else -1 then ;
: xxyy ( x y x y -- x x y y ) rot swap ;

here constant termio 64 allot
1 TCGETS termio ioctl drop 
termio 12 + dup l@ ECHO not and swap l!
1 TCSETSF termio ioctl drop 
27 emit ." [?25l"
27 emit ." [H" 27 emit ." [J"

: quit 
  27 emit ." [?25h"
  termio 12 + dup l@ ECHO or swap l!
  1 TCSETSF termio ioctl drop 
  bye ;

1 TIOCGWINSZ pad ioctl drop
pad w@         constant height 
pad word+ w@   constant width
width height * constant size 
here           constant screen size allot
0   constant  MENU
1   constant  COMPUTER
2   constant  FRIEND
3   constant  WIN
0   variable  mode
0   variable  cursor
9   variable  player1
9   variable  player2
0   variable  score1
0   variable  score2
0 0 variable2 velocity
0 0 variable2 ball

: new-round
  score1 @ 10 >= 
  score2 @ 10 >= 
  or if WIN mode ! then
  score1 @ score2 @ > if -1 else 1 then 
  -1 velocity !2 
  width 2 / height 2 / ball !2 ;

: new-game
  0 score1 !
  0 score2 !
  new-round ;

: target ( -- x y ) ball @2 velocity @2 xxyy + -rot + swap ;  
: flight target ball !2 ;
: collision? ( y -- f ) dup height >= swap 0 < or ;
: rebound ( -- ) velocity @2 negate velocity !2 ;

: walls 
  target swap drop 
  collision? if rebound then ;

: racket-x? ( x px -- f ) if width >= else 0 <= then ;
: racket-y? ( y py -- f ) 2 + - abs 2 <= ;
: racket? ( x y px py -- f ) xxyy racket-y? -rot racket-x? and ;
: power* ( n -- n ) player1 @ player2 @ + 4 mod 1 max * -3 max 3 min ;
: hit velocity @2 swap power* negate swap velocity !2 ;

: players 
  target 0 player1 @ racket? 
  target 1 player2 @ racket? 
  or if hit then ; 
  
: check-goal 
  target drop dup 
  width >= if drop 1 score1 !+ new-round leave then 
  0 <= if 1 score2 !+ new-round then ;

: physics walls players check-goal flight ;

: key ( -- n )
  0 pad
  pad long+ POOLIN swap w!
  pad 1 0 pool drop
  pad long+ word+ w@ POOLIN and if 
    0 pad 100 accept drop pad c@
  else 0 then ;

: moving ( n player -- ) dup @ rot + 0 max height 4 - min swap ! ;

: input 
  key 
  [char] q case -3 player1 moving end
  [char] a case 3 player1 moving end
  [char] p case -3 player2 moving end
  [char] l case 3 player2 moving end
  [char] e case quit end
  drop ;

: visible? 
  velocity @ 0 >
  ball @ width 2 / > and 
  mode @ COMPUTER = and ;
  
: ai 
  visible? if 
    ball cell+ @ player2 @ - negate 
    -1/1 player2 moving 
  then ;

: clear screen size 32 fill ;
: flush screen size .s ;
: point ( x y c -- ) -rot width * + screen + c! ;
: draw-ball ball @2 [char] @ point ;

: draw-player ( x y -- ) 
  4 for 
    dup2 [char] # point 1+ 
  next drop2 ;

: draw-players 
  0 player1 @ draw-player 
  width 1- player2 @ draw-player ;

: draw-border 
  width 2 / 0 height for 
    dup2 [char] | point 1+ 
  next drop2 ;

: draw-score ( score x -- ) 
  3 width * + screen + swap <# #u #> rot swap move ;

: draw-scores 
  score1 @ width 2 / 7 - draw-score 
  score2 @ width 2 / 7 + draw-score ;

: draw draw-border draw-scores draw-ball draw-players ;

: label ( str u )
  dup 2 / width 2 / swap -
  cursor @ width * + screen + swap move
  1 cursor !+ ;

: win 
  height 2 / 4 - cursor !
  score1 @ score2 @ > if
    " Player1 WIN!"
  else
    " Player2 WIN!"
  then
  label
  " Press C to continue" label
  key 
  [char] c case 0 mode ! end
  [char] e case quit end
  drop ;

: menu 
  height 2 / 4 - cursor !
  " PONG" label
  " Q - Player 1 Up, A - Player 1 Down" label
  " P - Player 2 Up, L - Player 2 Down" label
  " E - Exit" label
  " " label
  " " label
  " 1. Play with computer" label
  " 2. Play with friend" label
  key 
  [char] 1 case new-game COMPUTER mode ! end
  [char] 2 case new-game FRIEND mode ! end
  [char] e case quit end
  drop ;
 
: game input ai physics draw ;

: pong 
  @:> clear mode @
    dup MENU = if menu then
    dup dup COMPUTER = swap FRIEND = or if game then
    WIN = if win then
    60 ms
  flush <@ ; pong