{
                         N I B B L E S  v1.0
                                 by
                        Tomas Kruska 1998/99

  Nibbles is a game for one or two players.  Navigate your snakes
  around the game board trying to eat up numbers while avoiding
  running into walls or other snakes.  The more numbers you eat up,
  the more points you gain and the longer your snake becomes.
}

program Nibbles;

{$IFDEF DPMI}
  !!! Nibbles can NOT be compiled in PROTECTED MODE !!!
{$ENDIF}
{$IFDEF WINDOWS}
  !!! Nibbles can NOT be compiled in WINDOWS MODE !!!
{$ENDIF}

uses Crt, Game, Grafix, HiScore, Keyb, Menus;

const
  { Menu Commands }
  cmOnePlayer = 1;
  cmTwoPlayers = 2;
  cmEasy = 3;
  cmMedium = 4;
  cmHard = 5;
  cmVeryHard = 6;
  cmHiScores = 7;
  cmCredits = 8;
  cmQuit = 9;
  cmControls = 10;

  { Difficulty texts }
  DiffTxt: array[1..4] of string[9] = ('Easy     ',
                                       'Medium   ',
                                       'Hard     ',
                                       'Very Hard');
var
  HiScores: THiScoreTable;

{ Initialize the menus, game, ... }
procedure Init;
var
  W: TWindow;

begin
  TextColor(7);
  TextBackGround(0);
  ClrScr;
  TextMode(CO80 + Font8x8);

  HideCursor;
  Randomize;

  W.X1 := 2;
  W.X2 := 22;
  W.Y1 := 13;
  W.Y2 := 27;

  InitMenu(W, NewMenu(
    NewSubMenu('Play', NewMenu(
      NewItem('One Player', cmOnePlayer,
      NewItem('Two Players', cmTwoPlayers,
      NewItem('Back ...', cmBack,
      nil)))),
    NewSubMenu('Change Difficulty', NewMenu(
      NewItem(DiffTxt[1], cmEasy,
      NewItem(DiffTxt[2], cmMedium,
      NewItem(DiffTxt[3], cmHard,
      NewItem(DiffTxt[4], cmVeryHard,
      NewItem('Back ...', cmBack,
      nil)))))),
    NewItem('Hall Of Fame', cmHiScores,
    NewItem('Controls', cmControls,
    NewItem('Credits', cmCredits,
    NewItem('Quit To System', cmQuit,
    nil)))))
  )));

  LoadScore(HiScores);
end;

procedure Logo;
var
  x, y: byte;

begin
  TextBackGround(8);
  ClrScr;
  TextColor(15);

  { Grid }
  For y := 1 to 50 do
    For x := 1 to 80 do
      Print(x, y, 1, 0,'Å');

  { Main logo }
  GotoXY(1,4);
  Write(' ÜŪŪŪŪŪÜ ŽŪŪŻ ŪŪŪŪŪŪÜ ŪŪŪŪŪŪÜ ŪŪ      ÜŪŪŪŪŪŪ ÜŪŪŪŪŪÜ                           ');
  Write(' ŪŪ   ŪŪ  ŪŪ  ŪŪÜÜÜŪß ŪŪÜÜÜŪß ŪŪ      ŪŪÜÜÜÜ  ŪŪÜÜÜÜ                            ');
  Write(' ŪŪ   ŪŪ  ŪŪ  ŪŪßßßŪŪ ŪŪßßßŪŪ ŪŪ      ŪŪßßßß   ßßßßŪŪ                           ');
  Write(' ŪŪ   ŪŪ ŽŪŪŻ ŪŪŪŪŪŪß ŪŪŪŪŪŪß ŪŪŪŪŪŪŪ ßŪŪŪŪŪŪ ßŪŪŪŪŪß                           ');

  { Mirrored logo }
  TextColor(7);
  GotoXY(1,45);
  Write('                           ÜŪŪŪŪŪÜ ŽŪŪŻ ŪŪŪŪŪŪÜ ŪŪŪŪŪŪÜ ŪŪ      ÜŪŪŪŪŪŪ ÜŪŪŪŪŪÜ ');
  Write('                           ŪŪ   ŪŪ  ŪŪ  ŪŪÜÜÜŪß ŪŪÜÜÜŪß ŪŪ      ŪŪÜÜÜÜ  ŪŪÜÜÜÜ  ');
  Write('                           ŪŪ   ŪŪ  ŪŪ  ŪŪßßßŪŪ ŪŪßßßŪŪ ŪŪ      ŪŪßßßß   ßßßßŪŪ ');
  Write('                           ŪŪ   ŪŪ ŽŪŪŻ ŪŪŪŪŪŪß ŪŪŪŪŪŪß ŪŪŪŪŪŪŪ ßŪŪŪŪŪŪ ßŪŪŪŪŪß ');

  { Some lines }
  GotoXY(1,3);
  Writeln('ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ');
  GotoXY(1,8);
  Writeln('ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ');
  GotoXY(1,44);
  Writeln('ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ');
  GotoXY(1,49);
  Writeln('ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ');

  { Menu text }
  TextBackGround(7);
  TextColor(15);
  GotoXY(3, 12);
  Write(' Your choice ...   ');

  { Difficulty pretext }
  TextColor(15);
  TextBackGround(0);
  GotoXY(2, 45);
  Write('You are feeling');

  { Hiscore or Credits window }
  Frame(32, 13, 73, 38, 1, 0);
end;

{ Draws Credits table }
procedure ViewCredits;
begin
  Frame(32, 13, 73, 38, 1, 0);

  TextColor(14);
  Center(53, 15, 'Credits');
  TextColor(15);
  Center(53, 16, 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ');

  Center(53, 22, 'NIBBLES v1.0');
  Center(53, 25, 'by');
  Center(53, 27, 'Tomas Claw Kruska');
  Center(53, 30, 'email: tkruska@email.cz');
  Center(53, 31, '        or kruskat@feld.cvut.cz');
end;

{ Draws score table }
procedure ViewScore;
var
  i: byte;
begin
  Frame(32, 13, 73, 38, 1, 0);

  TextColor(14);
  Center(53, 15, 'The Best Players');
  TextColor(15);
  Center(53, 16, 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ');

  { Draw hiscore table }
  For i := 1 to CMaxScores do
  begin
    TextColor(15);
    GotoXY(40, i * 2 + 16);
    Write(HiScores[i].Name);
    TextColor(13);
    GotoXY(58, i * 2 + 16);
    Write(HiScores[i].score: 7);
  end;

end;

{ Draws control configuration }
procedure ViewControls;
begin
  Frame(32, 13, 73, 38, 1, 0);

  TextColor(14);
  Center(53, 15, 'Game Controls');
  TextColor(15);
  Center(53, 16, 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ');

  GotoXY(43, 20); Write('Player:  ONE    TWO');
  GotoXY(43, 23); Write('Left   -  '#27'      A');
  GotoXY(43, 24); Write('Right  -  '#26'      F');
  GotoXY(43, 25); Write('Up     -  '#24'      W');
  GotoXY(43, 26); Write('Down   -  '#25'      S');

  GotoXY(43, 30); Write('General:');
  GotoXY(43, 32); Write('Pause  -  P');
  GotoXY(43, 33); Write('End    -  Esc');
end;

{ Get Best players name }
procedure GetPlayerName(score1, score2: longint);
var
  index: byte;
  name: string;
begin
  name := '';

  { Check first player's score }
  index := CheckScore(HiScores, score1);
  If index <> 0 then
  begin
    Frame(15, 21, 65, 28, ColorTable[4], 0);
    TextColor(14);
    Center(40, 23, 'Player ONE has high score !');
    TextColor(15);
    Center(40, 24, 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ');

    GotoXY(18, 26);
    Write('Please Enter your name :');

    { Read name }
    Input(43, 26, 15, name);
    UpDateScore(HiScores, index, name, score1);
  end;

  name := '';

  { Check second player's score }
  index := CheckScore(HiScores, score2);
  If index <> 0 then
  begin
    Frame(15, 21, 65, 28, ColorTable[4], 0);
    TextColor(14);
    Center(40, 23, 'Player TWO has high score !');
    TextColor(15);
    Center(40, 24, 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ');

    GotoXY(18, 26);
    Write('Please Enter your name :');

    { Read name }
    Input(43, 26, 15, name);
    UpDateScore(HiScores, index, name, score2);
  end;
end;

{ Run menu ...}
procedure Run;
var
  command: word;
  Skill: byte;
  Score1, Score2: longint;
  Index: byte;

begin
  Logo;

  Skill := 2;
  repeat
    { Draw difficulty text }
    GotoXY(18, 45);
    TextColor(14);
    TextBackGround(0);
    Write(DiffTxt[Skill]);

    { Get command /run menu/ }
    command := RunMenu;

    { Handle command }
    case Command of
      cmOnePlayer: begin
                     InitGame(Skill, 1);
                     PlayGame(Score1, Score2);
                     GetPlayerName(Score1, 0);
                     Logo;
                   end;
      cmTwoPlayers: begin
                      InitGame(Skill, 2);
                      PlayGame(Score1, Score2);
                      GetPlayerName(Score1, Score2);
                      Logo;
                    end;
      cmHiScores: ViewScore;
      cmCredits : ViewCredits;
      cmControls: ViewControls;

      cmEasy    : Skill := 1;
      cmMedium  : Skill := 2;
      cmHard    : Skill := 3;
      cmVeryHard: Skill := 4;
    end;
  until Command = cmQuit;
end;

{ Done game }
procedure Done;
begin
  DoneMenu;
  SaveScore(HiScores);
  ShowCursor;

  TextColor(7);
  TextBackGround(0);
  ClrScr;
  Writeln('NIBBLES v1.0 by Tomas Claw Kruska /tkruska@email.cz, kruskat@feld.cvut.cz/');
end;

{ Main }
begin
  Init;
  Run;
  Done;
end.
