(********************************************************************)
(*                                                                  *)
(*  pairs.sd7     Concentration game                                *)
(*  Copyright (C) 2005  Thomas Mertes                               *)
(*                                                                  *)
(*  This program is free software; you can redistribute it and/or   *)
(*  modify it under the terms of the GNU General Public License as  *)
(*  published by the Free Software Foundation; either version 2 of  *)
(*  the License, or (at your option) any later version.             *)
(*                                                                  *)
(*  This program is distributed in the hope that it will be useful, *)
(*  but WITHOUT ANY WARRANTY; without even the implied warranty of  *)
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   *)
(*  GNU General Public License for more details.                    *)
(*                                                                  *)
(*  You should have received a copy of the GNU General Public       *)
(*  License along with this program; if not, write to the           *)
(*  Free Software Foundation, Inc., 51 Franklin Street,             *)
(*  Fifth Floor, Boston, MA  02110-1301, USA.                       *)
(*                                                                  *)
(********************************************************************)


$ include "seed7_05.s7i";
  include "float.s7i";
  include "text.s7i";
  include "draw.s7i";
  include "stdfont9.s7i";
  include "pixmap_file.s7i";
  include "keybd.s7i";
  include "dialog.s7i";
  include "chartype.s7i";
  include "time.s7i";
  include "duration.s7i";
  include "pic32.s7i";


const integer: WINDOW_WIDTH is 992;
const integer: WINDOW_HEIGHT is 704;
const integer: CARD_SIZE is 64;
const integer: CARD_BORDER is 3;
const integer: FIELD_SIZE is CARD_SIZE + 2 * CARD_BORDER;
const integer: FIELD_LINES is 6;
const integer: FIELD_COLUMNS is 14;
const integer: UPPER_BORDER is (WINDOW_HEIGHT - FIELD_LINES * FIELD_SIZE) div 2;
const integer: LEFT_BORDER is (WINDOW_WIDTH - FIELD_COLUMNS * FIELD_SIZE) div 2;
const integer: COMPUTER_HIT_YPOS is (UPPER_BORDER + CARD_BORDER - 2 * FIELD_SIZE) div 2;
const integer: OPPONENT_XPOS is 76;
const integer: OPPONENT_YPOS is (UPPER_BORDER + CARD_BORDER - 128) div 2;

var PRIMITIVE_WINDOW: opponent is PRIMITIVE_WINDOW.value;
var array PRIMITIVE_WINDOW: digit_pixmap is 0 times PRIMITIVE_WINDOW.value;

const type: cardType is new struct
    var array string: picture is 0 times "";
    var PRIMITIVE_WINDOW: pixmap is PRIMITIVE_WINDOW.value;
    var integer: number is 0;
  end struct;

const type: visibleType is new enum
    backSide, frontSide, removed
  end enum;

const type: fieldType is new struct
    var integer: cardNumber is 0;
    var visibleType: visible is backSide;
    var boolean: visited is FALSE;
  end struct;

const type: gameObj is new struct
    var integer: currLevel is 2;
    var integer: playerHits is 0;
    var integer: computerHits is 0;
    var integer: player_hit_ypos is 0;
    var boolean: quit is FALSE;
  end struct;

var gameObj: game is gameObj.value;


const array string: size_2_5 is [](
  "           YYYYY                ",
  "          YYYYYYY               ",
  "          YYBWBYY               ",
  "          YYWOWYY               ",
  "            WWW                 ",
  "          OOOOOOO               ",
  "         OOOOOOOOO              ",
  "        WO OOMOO OW             ",
  "       WW  MMMMM  WW            ",
  "       bWWWbbbbbWWWb            ",
  "       bbbWWbbbWWbbb            ",
  "                                ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W WWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W WWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  "                                ",
  "           WW    WWWWW          ",
  "            W    W   W          ",
  "            W    W   W          ",
  "            W    W   W          ",
  "          WWWWW  WWWWW          ",
  "                                ");


const array string: size_3_4 is [](
  "           YYYYY                ",
  "          YYYYYYY               ",
  "          YYBWBYY               ",
  "          YYWOWYY               ",
  "            WWW                 ",
  "          OOOOOOO               ",
  "         OOOOOOOOO              ",
  "        WO OOMOO OW             ",
  "       WW  MMMMM  WW            ",
  "       bWWWbbbbbWWWb            ",
  "       bbbWWbbbWWbbb            ",
  "                                ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W WWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W WWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W WWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  "                                ",
  "           WW    WWWWW          ",
  "            W        W          ",
  "            W    WWWWW          ",
  "            W    W              ",
  "          WWWWW  WWWWW          ",
  "                                ");


const array string: size_4_4 is [](
  "           YYYYY                ",
  "          YYYYYYY               ",
  "          YYBWBYY               ",
  "          YYWOWYY               ",
  "            WWW                 ",
  "          OOOOOOO               ",
  "         OOOOOOOOO              ",
  "        WO OOMOO OW             ",
  "       WW  MMMMM  WW            ",
  "       bWWWbbbbbWWWb            ",
  "       bbbWWbbbWWbbb            ",
  "                                ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W WWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W WWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W WWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W WWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  "                                ",
  "           WW    WWWW           ",
  "            W    W              ",
  "            W    WWWWW          ",
  "            W    W   W          ",
  "          WWWWW  WWWWW          ",
  "                                ");


const array string: size_4_5 is [](
  "           YYYYY                ",
  "          YYYYYYY               ",
  "          YYBWBYY               ",
  "          YYWOWYY               ",
  "            WWW                 ",
  "          OOOOOOO               ",
  "         OOOOOOOOO              ",
  "        WO OOMOO OW             ",
  "       WW  MMMMM  WW            ",
  "       bWWWbbbbbWWWb            ",
  "       bbbWWbbbWWbbb            ",
  "                                ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W WWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W WWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W WWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W WWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  "                                ",
  "          WWWWW  WWWWW          ",
  "              W  W   W          ",
  "          WWWWW  W   W          ",
  "          W      W   W          ",
  "          WWWWW  WWWWW          ",
  "                                ");


const array string: size_4_6 is [](
  "           YYYYY                ",
  "          YYYYYYY               ",
  "          YYBWBYY               ",
  "          YYWOWYY               ",
  "            WWW                 ",
  "          OOOOOOO               ",
  "         OOOOOOOOO              ",
  "        WO OOMOO OW             ",
  "       WW  MMMMM  WW            ",
  "       bWWWbbbbbWWWb            ",
  "       bbbWWbbbWWbbb            ",
  "                                ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  "                                ",
  "          WWWWW  W              ",
  "              W  W W            ",
  "          WWWWW  WWWWW          ",
  "          W        W            ",
  "          WWWWW    W            ",
  "                                ");


const array string: size_5_6 is [](
  "           YYYYY                ",
  "          YYYYYYY               ",
  "          YYBWBYY               ",
  "          YYWOWYY               ",
  "            WWW                 ",
  "          OOOOOOO               ",
  "         OOOOOOOOO              ",
  "        WO OOMOO OW             ",
  "       WW  MMMMM  WW            ",
  "       bWWWbbbbbWWWb            ",
  "       bbbWWbbbWWbbb            ",
  "                                ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  "                                ",
  "          WWWWW  WWWWW          ",
  "              W  W   W          ",
  "          WWWWW  W   W          ",
  "              W  W   W          ",
  "          WWWWW  WWWWW          ",
  "                                ");


const array string: size_6_6 is [](
  "           YYYYY                ",
  "          YYYYYYY               ",
  "          YYBWBYY               ",
  "          YYWOWYY               ",
  "            WWW                 ",
  "          OOOOOOO               ",
  "         OOOOOOOOO              ",
  "        WO OOMOO OW             ",
  "       WW  MMMMM  WW            ",
  "       bWWWbbbbbWWWb            ",
  "       bbbWWbbbWWbbb            ",
  "                                ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W WWWWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  "                                ",
  "          WWWWW  WWWW           ",
  "              W  W              ",
  "          WWWWW  WWWWW          ",
  "              W  W   W          ",
  "          WWWWW  WWWWW          ",
  "                                ");


const array string: size_6_7 is [](
  "           YYYYY                ",
  "          YYYYYYY               ",
  "          YYBWBYY               ",
  "          YYWOWYY               ",
  "            WWW                 ",
  "          OOOOOOO               ",
  "         OOOOOOOOO              ",
  "        WO OOMOO OW             ",
  "       WW  MMMMM  WW            ",
  "       bWWWbbbbbWWWb            ",
  "       bbbWWbbbWWbbb            ",
  "                                ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W WWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W WWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W WWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W WWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W WWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W WWWWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  "                                ",
  "          W      WWWWW          ",
  "          W W        W          ",
  "          WWWWW  WWWWW          ",
  "            W    W              ",
  "            W    WWWWW          ",
  "                                ");


const array string: size_6_8 is [](
  "           YYYYY                ",
  "          YYYYYYY               ",
  "          YYBWBYY               ",
  "          YYWOWYY               ",
  "            WWW                 ",
  "          OOOOOOO               ",
  "         OOOOOOOOO              ",
  "        WO OOMOO OW             ",
  "       WW  MMMMM  WW            ",
  "       bWWWbbbbbWWWb            ",
  "       bbbWWbbbWWbbb            ",
  "                                ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W WWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W WWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W WWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W WWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W WWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W WWWWWWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  "                                ",
  "          W      WWWWW          ",
  "          W W    W   W          ",
  "          WWWWW  WWWWW          ",
  "            W    W   W          ",
  "            W    WWWWW          ",
  "                                ");


const array string: size_6_10 is [](
  "           YYYYY                ",
  "          YYYYYYY               ",
  "          YYBWBYY               ",
  "          YYWOWYY               ",
  "            WWW                 ",
  "          OOOOOOO               ",
  "         OOOOOOOOO              ",
  "        WO OOMOO OW             ",
  "       WW  MMMMM  WW            ",
  "       bWWWbbbbbWWWb            ",
  "       bbbWWbbbWWbbb            ",
  "                                ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W WWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W WWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W WWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W WWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W WWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W WWWWWWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  "                                ",
  "          WWWW   WWWWW          ",
  "          W      W   W          ",
  "          WWWWW  W   W          ",
  "          W   W  W   W          ",
  "          WWWWW  WWWWW          ",
  "                                ");


const array string: size_6_12 is [](
  "           YYYYY                ",
  "          YYYYYYY               ",
  "          YYBWBYY               ",
  "          YYWOWYY               ",
  "            WWW                 ",
  "          OOOOOOO               ",
  "         OOOOOOOOO              ",
  "        WO OOMOO OW             ",
  "       WW  MMMMM  WW            ",
  "       bWWWbbbbbWWWb            ",
  "       bbbWWbbbWWbbb            ",
  "                                ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W W W WWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W W W WWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W W W WWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W W W WWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W W W WWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W W W WWWWWW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  "                                ",
  "          WWWWW  WWWWW          ",
  "              W      W          ",
  "             W   WWWWW          ",
  "            W    W              ",
  "            W    WWWWW          ",
  "                                ");


const array string: size_6_14 is [](
  "           YYYYY                ",
  "          YYYYYYY               ",
  "          YYBWBYY               ",
  "          YYWOWYY               ",
  "            WWW                 ",
  "          OOOOOOO               ",
  "         OOOOOOOOO              ",
  "        WO OOMOO OW             ",
  "       WW  MMMMM  WW            ",
  "       bWWWbbbbbWWWb            ",
  "       bbbWWbbbWWbbb            ",
  "                                ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W W W W W WW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W W W W W WW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W W W W W WW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W W W W W WW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W W W W W WW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  " W W W W W W W W W W W W W W WW ",
  " WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW ",
  "                                ",
  "          WWWWW  W              ",
  "          W   W  W W            ",
  "          WWWWW  WWWWW          ",
  "          W   W    W            ",
  "          WWWWW    W            ",
  "                                ");


const array string: panic_monster1_pic is [](
  "                ",
  "                ",
  "                ",
  " B           B  ",
  " B           B  ",
  " BBBBB   BBBBB  ",
  "      OOO       ",
  "    OOOOOOO     ",
  "  O      B  O   ",
  "  O      B  O   ",
  "  O         O   ",
  "  OOOOOOOOOOO   ",
  "    O     O     ",
  "                ",
  "                ",
  "                ");


const array string: panic_monster2_pic is [](
  "                ",
  "                ",
  "                ",
  "   G       G    ",
  "   G       G    ",
  " GGGGG   GGGGG  ",
  " GGGGG   GGGGG  ",
  " G  M  G  M  G  ",
  " G     G     G  ",
  " GGGGGGGGGGGGG  ",
  "   GGGGGGGGG    ",
  "   OOO   OOO    ",
  " OOO       OOO  ",
  "                ",
  "                ",
  "                ");


const array string: panic_monster3_pic is [](
  "                ",
  "                ",
  "                ",
  "   B       B    ",
  "   BBB   BBB    ",
  " BBBBB   BBBBB  ",
  " BBBBB   BBBBB  ",
  "   B  OOO  B    ",
  "   B  OOO  B    ",
  "   BBB   BBB    ",
  "   B   B   B    ",
  "     BBBBB      ",
  "     B   B      ",
  "                ",
  "                ",
  "                ");


const array string: dig_right_pic is [](
  "  WWWWW         ",
  "  WW WWW        ",
  "  WWWWW         ",
  "   WWW          ",
  "    W           ",
  "  WWWWWW        ",
  "  WWWW WW       ",
  "   WWWW WW      ",
  "   WWWWWWW      ",
  "   WWW  WW      ",
  "  WW WW  WW     ",
  "  WW WW   WW    ",
  "  WW WW    WWW  ",
  "  WW WW    WWW  ",
  "  WW WW     WW  ",
  " WWW WWW     W  ");


const array string: big_bush_pic is [](
  "     G G  GG  G  G   G G        ",
  "      GG   G  G G    GGGGG      ",
  "       G    G GG    gg G   G  G ",
  "    GGGGG    GGG G gg  G   G GG ",
  " G     Ggg G  gg Ggg   G   gg   ",
  " GG   G  ggG  gg gg   gG  ggGG  ",
  "   G      gg  ggggG  gg  gg     ",
  " G  GGGGggggg ggg   gg  ggggGGGG",
  "  G  G      bbbb    bbggg       ",
  "GGGG   G  G  bbb   bbgg G    GG ",
  "   gg   GG G  bb  bb  G   G  G  ",
  " GGGgg   G  ggbb bb G   G GggGGG",
  "     gg  gG  gbbbb  G gg  gg    ",
  "  G   gg g bb bbb   ggg  ggggGG ",
  " GGG   gbg  bbbb  G gg  gg G    ",
  "    G   bg   bbb G  g  gg   G   ",
  "  G  G   gb   bbbb  bbbb  G    G",
  "   g  g  gbb  bbb   bbbg  G  GG ",
  "GGGgggggbb bb bb  G bb    gg G  ",
  "       bbb  bbbb  GbbggGG ggg   ",
  "  G  GGGbb  Gbbb  bb      ggGGG ",
  "   G     bb   bb bbggGG  gg     ",
  "    gg G  bb  bbbb      ggggGGGG",
  " GGggggG GGbb bbb      gggg     ",
  "   G  gg    bbbb   G  bb  GGGG  ",
  "  G    ggG   bbb  G  bb    G    ",
  "     G  gg  G bbgg  bb          ",
  "  GGgggggbb  Gbbg  bbbggggGGGG  ",
  "    G     bb  bb  bb   G        ",
  "       GGGGbb bb bb     G       ",
  "            bbbbbbGGGG          ",
  "             bbbb               ");


const array string: chain_pic is [](
  "     BBB   BBB  ",
  "    B   B B   B ",
  "    B  BBBBB  B ",
  "    BB  B B   B ",
  "    BBBB   BBB  ",
  "   BB           ",
  " BBB            ",
  "B B B           ",
  "B   B           ",
  "B B B           ",
  " BBB            ",
  "   BBBBB   BBB  ",
  "    BB  B B   B ",
  "    B  BBBBB  B ",
  "    B   B B   B ",
  "     BBB   BBB  ");


const array string: large_gem_pic is [](
  "                                ",
  "                                ",
  "     RRRRRR          RRRRRR     ",
  "   RRRRRRRRRR      RRRRRRRRRR   ",
  "  RRRrrrrrrRRR    RRRrrrrrrRRR  ",
  " RRrrrrrrrrrrRR  RRrrrrrrrrrrRR ",
  " RRrrrrrrrrrrrRRRRrrrrrrrrrrrRR ",
  "RRrrrrrrrrrrrrrRRrrrrrrrrrrrrrRR",
  "RRrrrrrrrrrrrrrrrrrrrrrrrrrrrrRR",
  "RRrrrrrrrrrrrrrrrrrrrrrrrrrrrrRR",
  "RRrrrrrrrrrrrrrrrrrrrrrrrrrrrrRR",
  "RRrrrrrrrrrrrrrrrrrrrrrrrrrrrrRR",
  "RRrrrrrrrrrrrrrrrrrrrrrrrrrrrrRR",
  "RRrrrrrrrrrrrrrrrrrrrrrrrrrrrrRR",
  "RRrrrrrrrrrrrrrrrrrrrrrrrrrrrrRR",
  " RRrrrrrrrrrrrrrrrrrrrrrrrrrrRR ",
  " RRrrrrrrrrrrrrrrrrrrrrrrrrrrRR ",
  "  RRrrrrrrrrrrrrrrrrrrrrrrrrRR  ",
  "   RRrrrrrrrrrrrrrrrrrrrrrrRR   ",
  "    RRrrrrrrrrrrrrrrrrrrrrRR    ",
  "     RRrrrrrrrrrrrrrrrrrrRR     ",
  "      RRrrrrrrrrrrrrrrrrRR      ",
  "       RRrrrrrrrrrrrrrrRR       ",
  "        RRrrrrrrrrrrrrRR        ",
  "         RRrrrrrrrrrrRR         ",
  "          RRrrrrrrrrRR          ",
  "           RRrrrrrrRR           ",
  "            RRrrrrRR            ",
  "             RRrrRR             ",
  "              RRRR              ",
  "               RR               ",
  "                                ");


const array string: fairy_pic is [](
  "      xxxxx                   YYYY                   xxxxx      ",
  "    xxxcccxxx               YYYYYYYY               xxxcccxxx    ",
  "   xxcccccccxx             YYYYYYYYYY             xxcccccccxx   ",
  "  xxcccccccccxx           YYYYYYYYYYYY           xxcccccccccxx  ",
  "  xcccccccccccxx          YYYWWWWWWYYY          xxcccccccccccx  ",
  "  xccccccccccccxx        YYYWWWWWWWWYYY        xxccccccccccccx  ",
  "  xxccccccccccccxx       YYYWBBWWBBWYYY       xxccccccccccccxx  ",
  "   xcccccccccccccxx      YYYWWWWWWWWYYY      xxcccccccccccccx   ",
  "   xxcccccccccccccxx     YYYWWWWWWWWYYY     xxcccccccccccccxx   ",
  "    xxxccccccccccccxx    YYYWWOWWOWWYYY    xxccccccccccccxxx    ",
  "   xxcccccBccccBccccxx   YYYWWWOOWWWYYY   xxcccccccccccccccxx   ",
  "   xcccccccBccBccccccxx      WWWWWW      xxcccccccccccccccccx   ",
  "  xxccccccccccccccccccxx      WWWW      xxccccccccccccccccccxx  ",
  "  xccccccBBcWWcBBccccccxx     WWWW     xxccccccccccccccccccccx  ",
  "  xcccccccccWWccccccccccxWWWWWWWWWWWWWWxcccccccccccccccccccccx  ",
  "  xxccccccBcRRcBcccccccWWWWWWWWWWWWWWWWWWcccccccccccccccccccxx  ",
  "   xcccccBccRRccBcccccWWWWWWWWWWWWWWWWWWWWccccccccccccccccccx   ",
  "   xxcccccccRRcccccccWWWWWRRRWWWWWWRRRWWWWWccccccccccccccccxx   ",
  "    xxxcccccRRccccccWWWWWRRRRRWWWWRRRRRWWWWWcccccccccccccxxx    ",
  "   xxcccccccRRcccccWWWWWRRRRRRRWWRRRRRRRWWWWWccccccccccccccxx   ",
  "   xccccccccRRccccWWWWWcRRRRRRRWWRRRRRRRcWWWWWccccccccccccccx   ",
  "  xxccccccccRRcccWWWWWccRRRRRRRWWRRRRRRRccWWWWWcccccccccccccxx  ",
  "  xcccccccccRRccWWWWWcccxRRRRRWWWWRRRRRxcccWWWWWcccccccccccccx  ",
  "  xcccccccccRRcWWWWWcccxxcRRRWWWWWWRRRcxxcccWWWWWccccccccccccx  ",
  "  xxccccccccRRWWWWWcccxx   WWWWWWWWWW   xxcccWWWWWccccccccccxx  ",
  "   xcccccccWWWWWWWcccxx    WWWWWWWWWW    xxcccWWWWWWWWccccccx   ",
  "   xxcccccWWWWWWWcccxx     WWWWWWWWWW     xxcccWWWWWWccccccxx   ",
  "    xxxcccWWWWWWcccxx      WWWWYYWWWW      xxcccWWWWWWcccxxx    ",
  "   xxcccccWWWWWcccxx      WWWWWYYWWWWW      xxccWWWWWWWccccxx   ",
  "   xcccccccWWWcccxx       WWWWWWWWWWWW       xxccWWWWWccccccx   ",
  "  xxccccccccccccxx       WWWWWWWWWWWWWW       xxccWWccccccccxx  ",
  "  xccccccccccccxx       RRRRRRRRRRRRRRRR       xxccccccccccccx  ",
  "  xcccccccccccxx        WWRRRRRRRRRRRRWW        xxcccccccccccx  ",
  "  xxcccccccccxx        WWWWWRRRRRRRRWWWWW        xxcccccccccxx  ",
  "   xxcccccccxx         WWWWWWRRRRRRWWWWWW         xxcccccccxx   ",
  "    xxxcccxxx          WWWWWWWRRRRWWWWWWW          xxxcccxxx    ",
  "      xxxxx            WWWWWWWRRRRWWWWWWW            xxxxx      ",
  "                       WWWWWWWWRRWWWWWWWW                       ",
  "                        WWWWWWWRRWWWWWWW                        ",
  "                        WWWWWWW  WWWWWWW                        ",
  "                         WWWWWW  WWWWWW                         ",
  "                         WWWWWW  WWWWWW                         ",
  "                         WWWWWW  WWWWWW                         ",
  "                         WWWWWW  WWWWWW                         ",
  "                          WWWWW  WWWWW                          ",
  "                          WWWWW  WWWWW                          ",
  "                          WWWWW  WWWWW                          ",
  "                          WWWWW  WWWWW                          ",
  "                          WWWWW  WWWWW                          ",
  "                          WWWWW  WWWWW                          ",
  "                           WWWW  WWWW                           ",
  "                           WWWW  WWWW                           ",
  "                           WWWW  WWWW                           ",
  "                           WWWW  WWWW                           ",
  "                           WWWW  WWWW                           ",
  "                           WWWW  WWWW                           ",
  "                           WWWW  WWWW                           ",
  "                           WWWW  WWWW                           ",
  "                           WWWW  WWWW                           ",
  "                           WWWW  WWWW                           ",
  "                           WWWW  WWWW                           ",
  "                          WWWWW  WWWWW                          ",
  "                         WWWWWW  WWWWWW                         ",
  "                         WWWWWW  WWWWWW                         ");


const array string: computer_pic is [](
  "ccccccccccccccccccc                                 YYYYY       ",
  "ccccccccccccccccccc                                YYYYYYY      ",
  "cc               cc                               YYYYYYYY      ",
  "cc WWW  R R  WWW cc                               YYYYYYYYY     ",
  "cc  W  RRRRR WWW cc                               YYYYYYYYY     ",
  "cc  W  RRRRR  W  cc                                WWWYYYYY     ",
  "cc  W   RRR  WWW cc                                cWWYYYYY     ",
  "cc  W   RRR   W  cc                               WWWWYYYYY     ",
  "cc WWW   R   W W cc                               WWWWRYYYY     ",
  "cc               cc                                WWWYYYYY     ",
  "cc ccccccccccc   cc                                OWWYYYYY     ",
  "cc WWWWWWWWWWW   cc                                WWWWW        ",
  "cc W         W   cc                                 WWW         ",
  "cc W WWWW WW W   cc                                 WWW         ",
  "cc W         W   cc                                RRRRR  GGG   ",
  "cc W   ccccccccc cc                                RRRRR GGGG   ",
  "cc W W WWWWWWWWW cc                                RRRRRRGGGG   ",
  "cc W   W       W cc                               RRRRRRRGGGG cc",
  "cc WWWWW  RRGG W cc                              RRRRRRRRGGGG cc",
  "cc     W RRRR  W cc                             RRRRRRRRRGGGGccc",
  "cc     W  RR   W cc                             RRRRRRRRRGGGGccc",
  "cc     WWWWWWWWW cc                             RRRRRRRRRGGGGccc",
  "cc               cc                              RRRRRRRRGGGGccc",
  "ccccccccccccccccccc                               RRRRRRRGGGG cc",
  "ccccccccccccccccccc                               RRRRRRRGGGG cc",
  "       xxxxx      R   G  R                       RRRRRRRRGGGG cc",
  "       xxxxx       R  G R                        RRRRRRRRGGGG cc",
  "       xxxxx        R GR                        RRRRRRRRR GGG cc",
  "xxxxxxxxxxxxxxxxxxx BBBB                     RRRRRRRRRRRR     cc",
  "xxxxxxxxxxxWWWWWWxx BBBB                  RRRRRRRRRRRRRRR     cc",
  "xxWWxxxxxxxxxxxxxxx BBBB  cccc  WWWWW  RRRRRRRRRR  RRRRRR     cc",
  "xxWWxxxxxxxWWWWWWxx BBBB  cccccccWWWWWWRRRRRRR     RRRRRR     cc",
  "xxxxxxxxxxxxxxxxxxx BBBB  cccccccccWWWWRRRR        GGGGGG     cc",
  "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb        GGGGGG     cc",
  "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb        BBBBBBB    cc",
  "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb       BBBBBBBB    cc",
  "  bbbb                  bbbb                  BBBBBBBBBBBBB   cc",
  "  bbbb                  bbbb              BBBBBBBBBBBBBBBBB   cc",
  "  bbbb                  bbbb          BBBBBBBBBBBBBBBBBBBBB   cc",
  "  bbbb                  bbbb       BBBBBBBBBBBBBBBBBBBBBBBB   cc",
  "  bbbb                  bbbb      BBBBBBBBBBBBBBBBBBBBBBBB    cc",
  "  bbbb                  bbbb     BBBBBBBBBBBBBBBBBBBBBBBBB    cc",
  "  bbbb                  bbbb     BBBBBBBBBBBBBBBBBBBBBBBB     cc",
  "  bbbb                  bbbb     BBBBBBBBBBBBBBBBBBBBBB       cc",
  "  bbbb                  bbbb     BBBBBBGGGGGGGGGGGGGGGGGGGGG  cc",
  "  bbbb                  bbbb     BBBBBGGGGGGGGGGGGGGGGGGGGGGG cc",
  "  bbbb            W     bbbb     BBBBBGGGGGGGGGGGGGGGGGGGGGGG cc",
  "  bbbb      W    WW     bbbb     BBBBBGGGGGGGGGGGGGGGGGGGGGGG cc",
  "  bbbb      WW  WWW     bbbb     BBBBB          ccc  cccccc  ccc",
  "  bbbb     WWW WWWW     bbbb     BBBBB          ccc ccccccccccc ",
  "  bbbb    xxxxxxxxxx    bbbb     BBBBB          ccc cccccccccc  ",
  "  bbbb    WxWxWxWxWx    bbbb     BBBBB          ccc             ",
  "  bbbb    xxxWxxxWxx    bbbb     BBBBB          ccc             ",
  "  bbbb    WxWxWxWxWx    bbbb     BBBBB          ccc             ",
  "  bbbb    xWxxxWxxxW    bbbb     BBBBB          ccc             ",
  "  bbbb    WxWxWxWxWx    bbbb     BBBBB          ccc             ",
  "  bbbb    xxxWxxxWxx    bbbb     BBBBB          ccc             ",
  "  bbbb    WxWxWxWxWx    bbbb     BBBBB          ccc             ",
  "  bbbb    xWxxxWxxxW    bbbb     BBBBB   ccccccccccccccccc      ",
  "  bbbb    WxWxWxWxWx    bbbb     BBBBB ccccccccccccccccccccc    ",
  "  bbbb    xxxWxxxWxx    bbbb     BBBBB ccccccccccccccccccccc    ",
  "  bbbb    WxWxWxWxWx    bbbb  RRRRRRRR bbb      bbb      bbb    ",
  "  bbbb    xWxxxWxxxW    bbbb RRRRRRRRR bbb      bbb      bbb    ",
  "  bbbb    xxxxxxxxxx    bbbb RRRRRRRRR bbb      bbb      bbb    ");


const array string: sea_pic is [](
  "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
  "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
  "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
  "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
  "cccccccccccccccccccccccccccccccccccccccccccccccOOOOOOOcccccccccc",
  "cccccccccccccccccccccccccccccccccccccccccccccOOOOOOOOOOOcccccccc",
  "cccccccccccccccccccccccccccccccccccccccccccOOOOOOOOOOOOOOOcccccc",
  "ccccccccccccccccccccccccccccccccccccccccccOOOOOOOOOOOOOOOOOccccc",
  "cccccccccccccccccccccccccccccccccccccccccOOOOOOOOOOOOOOOOOOOcccc",
  "cccccccccccccccccccccccccccccccccccccccccOOOOOOOOOOOOOOOOOOOcccc",
  "ccccccccccccccccccccccccccccccccccccccccOOOOOOOOOOOOOOOOOOOOOccc",
  "ccccccccccccccccccccccccccccccccccccccccOOOOOOOOOOOOOOOOOOOOOccc",
  "ccccccccccccccccccccccccccccccccccccccccOOOOOOOOOOOOOOOOOOOOOccc",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBOOOOBOOOOOBOOOOOBOOOOBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBOOOOOBOOOOOBOOOOOBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBOOOBOOOBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "BWWBBWWBBWWBBWWBBWWBBWWBBWWBBWWBBWWBBWWBBWWBBWWBBWWBBWWBBWWBBWWB",
  "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
  "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
  "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
  "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
  "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
  "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
  "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
  "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYY",
  "YYYYYbbbbbbYYYYYYYYYYYYYYYYYYYWRRRRWWWWYYYYYYYYYYYYYYYYYYYYYYYYY",
  "YYbbbbbbbbbYYYYYYYYYYYYYYYYYYWWRRRWWWWWWWYYYYYYYYYYYYYYYYYYYYYYY",
  "YbbbbWWWWWWYYYYYWWWRWWWWWWWWWWWRRWWWWWWWWWWYYYYYYYYYYYYYYYYYYYYY",
  "YbbbWWBWWWWWYYWWWWxRWWWWWWWWWWWRWWWWWWWWWWWWWYYYYYYYYYYYYYWWWYYY",
  "bbbbWWBWWOWWWWWWWWWWxxWWWWWWWWWRWWWWWWWWWWWWWWWYYYYYYWWWWWWWWWYY",
  "bbbbWWWWWWOWWWWWWWWWWWxxWWWWWWWRWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWY",
  "bbbbWWBWWOWWWWWWWWWWWWWWxxWWWWWRWWWWWWWWWWWWWWWWWWWWWWWWYYYYWWWY",
  "YbbbWWBWWWWWYYWWWRRRWWWWWWxxWWWRRWWWWWWWWWWWWWWWWWWWYYYYYYYYYWWW",
  "YbbbbWWWWWWYYYYYRRRRRWWWWWWWYYYYYYYYYYYYYYYYYYWWWWYYYYYYYYYYYYRW",
  "YGbbbbbbbbbGGGGGGRRRRRGGWWWWWWGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGY",
  "GGGGGGGGGGGGGGGGGGGGGGGGGGWWWWWWGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG",
  "GGGGGGGGGGGGGGGGGGWWWWWWWWWWWWWWGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG",
  "GGGGGGGGGGGGGGGWWWWWWWWWWWWWWWWWGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG",
  "GGGGGGGGGGGWWWWWWWWWWWWWWWWWWWWGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG",
  "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
  "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
  "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
  "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");


const array string: woman_pic is [](
  "                             YYYYYY                             ",
  "                           YYYYYYYYYY                           ",
  "                         YYYYYYYYYYYYYY                         ",
  "                        YYYYYYYYYYYYYYYY                        ",
  "                       YYYYYYYYYYYYYYYYYY                       ",
  "                      YYYYYYYYYYYYYYYYYYYY                      ",
  "                     YYYYYYYYYYYYYYYYYYYYYY                     ",
  "                    YYYYYYYYYYYYYYYYYYYYYYYY                    ",
  "                    YYYYYYYWWWWWWWWWWYYYYYYY                    ",
  "                   YYYYYYYWWWWWWWWWWWWYYYYYYY                   ",
  "                   YYYYYYWWWWWWWWWWWWWWYYYYYY                   ",
  "                  YYYYYYWWWWWWWWWWWWWWWWYYYYYY                  ",
  "                  YYYYYYWWWBBWWWWWWBBWWWYYYYYY                  ",
  "                  YYYYYYWWBBBBWWWWBBBBWWYYYYYY                  ",
  "                  YYYYYYWWWBBWWWWWWBBWWWYYYYYY                  ",
  "                  YYYYYYWWWWWWWWWWWWWWWWYYYYYY                  ",
  "                  YYYYYYWWWWWWWWWWWWWWWWYYYYYY                  ",
  "                  YYYYYYWWWWWWWWWWWWWWWWYYYYYY                  ",
  "                  YYYYYYWWWWWWWWWWWWWWWWYYYYYY                  ",
  "                  YYYYYYWWWWOOWWWWOOWWWWYYYYYY                  ",
  "                  YYYYYYWWWWWOOOOOOWWWWWYYYYYY                  ",
  "                  YYYYYY WWWWWOOOOWWWWW YYYYYY                  ",
  "                          WWWWWWWWWWWW                          ",
  "                           WWWWWWWWWW                           ",
  "                            WWWWWWWW                            ",
  "                            WWWWWWWW                            ",
  "                            WWWWWWWW                            ",
  "                           WWWWWWWWWW                           ",
  "                   OOOOOOOOWWWWWWWWWWOOOOOOOO                   ",
  "                OOOOOOOOOOOOWWWWWWWWOOOOOOOOOOOO                ",
  "              OOOOOOOOOOOOOOOOWWWWOOOOOOOOOOOOOOOO              ",
  "             OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO             ",
  "            OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO            ",
  "           OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO           ",
  "          OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO          ",
  "         OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO         ",
  "         WOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOW         ",
  "        WWWOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOWWW        ",
  "       WWWWWOOOOO  OOOOOOOOOOOOOOOOOOOOOOOOOO  OOOOOWWWWW       ",
  "      WWWWWWWOOO  OOOOOOOOOOOOOOOOOOOOOOOOOOOO  OOOWWWWWWW      ",
  "     WWWWWWWWWO   OOOOOOOOOOOOOOOOOOOOOOOOOOOO   OWWWWWWWWW     ",
  "    WWWWWWWWW     OOOOOOOOOOOOOOOOOOOOOOOOOOOO     WWWWWWWWW    ",
  "   WWWWWWWWW      OOOOOOOOOOOOMOOMOOOOOOOOOOOO      WWWWWWWWW   ",
  "  WWWWWWWWW        OOOOOOOOOOOOOOOOOOOOOOOOOO        WWWWWWWWW  ",
  " WWWWWWWWW         OOOOOOOOOOMOOOOMOOOOOOOOOO         WWWWWWWWW ",
  "WWWWWWWWW           OOOOOOOOMOOOOOOMOOOOOOOO           WWWWWWWWW",
  "WWWWWWWWW            OMOMOMOOOOOOOOOOMOMOMO            WWWWWWWWW",
  "WWWWWWWWWWWW         OOOOOOOOOOOOOOOOOOOOOO         WWWWWWWWWWWW",
  "WWWWWWWWWWWWWWW       OOOOOOOOOOOOOOOOOOOO       WWWWWWWWWWWWWWW",
  " WWWWWWWWWWWWWWWWW    OOOOOOOOOOOOOOOOOOOO    WWWWWWWWWWWWWWWWW ",
  "bbbbWWWWWWWWWWWWWWWWWbbbbbbbbbbbbbbbbbbbbbbWWWWWWWWWWWWWWWWWbbbb",
  "bbbbbbbWWWWWWWWWWWWWWWWWWWWWbbbbbbbbWWWWWWWWWWWWWWWWWWWWWbbbbbbb",
  "bbbbbbbbbbWWWWWWWWWWWWWWWbbbbbbbbbbbbbbWWWWWWWWWWWWWWWbbbbbbbbbb",
  "bbbbbbbbbbbbbWWWWWWWWWWWWWWbbbbbbbbbbWWWWWWWWWWWWWWbbbbbbbbbbbbb",
  "bbbbbbbbbbbbbbbbWWWWWWWWWWWWWbbbbbbWWWWWWWWWWWWWbbbbbbbbbbbbbbbb",
  "bbbbbbbbbbbbbbbbbWWWWWWWWWWWbbbbbbbbWWWWWWWWWWWbbbbbbbbbbbbbbbbb",
  "bbbbbbbbbbbbbbbbbbWWWWWWWWxxbbbbbbbbbbWWWWWWWWbbbbbbccccbbbbbbbb",
  "bbbbbbbbbbbbbbbbbbbbWWWWWxxxbbbbbbbbbbbWWWWWbbbbbbcccbbcccbbbbbb",
  "bbbbbbbbbbbbbbbbbbbbbxxxxxxxbbbbbbbbbbbbbbbbbbbbbccbbbbbbccbbbbb",
  "bbbbbbbbbbbbbbbbbbbbbcccccccbbbbbbbbbbbbbbbbbbbcccbbbbbbbbcbbbbb",
  "bbbbbbbbbbbbbbbbbbbbbbbbcbbbbbbbbbbbbbbbbbbbccccbbbbbbbbbbccbbbb",
  "bbbbbbbbbbbbbbbbbbbbbbbbccbbbbbbbbbbcccccccccbbbbbbbbbbbbbbcbbbb",
  "bbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccbbbbbbbbbbbbbbbbbbbbbbcbbbb",
  "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcbbbb");


const array string: zero is [](
  "                ",
  "                ",
  "   xBBBBBBBBBc  ",
  "  xBBc     xBBc ",
  "  xBc       xBc ",
  "  xBc       xBc ",
  "  xBc       xBc ",
  "  xBc       xBc ",
  "  xBc     xBBBc ",
  "  xBc    xBBBBc ",
  "  xBc    xBBBBc ",
  "  xBc    xBBBBc ",
  "  xBc    xBBBBc ",
  "  xBBc   xBBBBc ",
  "   xBBBBBBBBBc  ",
  "                ");


const array string: one is [](
  "                ",
  "                ",
  "     xBBBBc     ",
  "        xBc     ",
  "        xBc     ",
  "        xBc     ",
  "        xBc     ",
  "        xBc     ",
  "      xBBBc     ",
  "     xBBBBc     ",
  "     xBBBBc     ",
  "     xBBBBc     ",
  "     xBBBBc     ",
  "     xBBBBc     ",
  "  xBBBBBBBBBBc  ",
  "                ");


const array string: two is [](
  "                ",
  "                ",
  "   xBBBBBBBBBc  ",
  "  xBBc     xBBc ",
  "  xBc       xBc ",
  "            xBc ",
  "            xBc ",
  "            xBc ",
  "   xBBBBBBBBBc  ",
  "  xBBBBc        ",
  "  xBBBBc        ",
  "  xBBBBc        ",
  "  xBBBBc        ",
  "  xBBBBc        ",
  "  xBBBBBBBBBBBc ",
  "                ");


const array string: three is [](
  "                ",
  "                ",
  "   xBBBBBBBBBc  ",
  "  xBBc     xBBc ",
  "  xBc       xBc ",
  "            xBc ",
  "            xBc ",
  "            xBc ",
  "   xBBBBBBBBBc  ",
  "         xBBBBc ",
  "         xBBBBc ",
  "         xBBBBc ",
  "  xBc    xBBBBc ",
  "  xBBc   xBBBBc ",
  "   xBBBBBBBBBc  ",
  "                ");


const array string: four is [](
  "                ",
  "                ",
  "  xBc           ",
  "  xBc           ",
  "  xBc           ",
  "  xBc           ",
  "  xBc    xBc    ",
  "  xBc    xBc    ",
  "  xBBBBBBBBBBBc ",
  "      xBBBBc    ",
  "      xBBBBc    ",
  "      xBBBBc    ",
  "      xBBBBc    ",
  "      xBBBBc    ",
  "      xBBBBc    ",
  "                ");

const array string: five is [](
  "                ",
  "                ",
  "  xBBBBBBBBBBBc ",
  "  xBc           ",
  "  xBc           ",
  "  xBc           ",
  "  xBc           ",
  "  xBc           ",
  "  xBBBBBBBBBBc  ",
  "         xBBBBc ",
  "         xBBBBc ",
  "         xBBBBc ",
  "  xBc    xBBBBc ",
  "  xBBc   xBBBBc ",
  "   xBBBBBBBBBc  ",
  "                ");


const array string: six is [](
  "                ",
  "                ",
  "   xBBBBBBBBBc  ",
  "  xBBc     xBBc ",
  "  xBc       xBc ",
  "  xBc           ",
  "  xBc           ",
  "  xBc           ",
  "  xBBBBBBBBBBc  ",
  "  xBc    xBBBBc ",
  "  xBc    xBBBBc ",
  "  xBc    xBBBBc ",
  "  xBc    xBBBBc ",
  "  xBBc   xBBBBc ",
  "   xBBBBBBBBBc  ",
  "                ");


const array string: seven is [](
  "                ",
  "                ",
  "  xBBBBBBBBBBBc ",
  "            xBc ",
  "            xBc ",
  "            xBc ",
  "            xBc ",
  "           xBBc ",
  "      xBBBBBBc  ",
  "     xBBBBc     ",
  "     xBBBBc     ",
  "     xBBBBc     ",
  "     xBBBBc     ",
  "     xBBBBc     ",
  "     xBBBBc     ",
  "                ");


const array string: eight is [](
  "                ",
  "                ",
  "   xBBBBBBBBBc  ",
  "  xBBc     xBBc ",
  "  xBc       xBc ",
  "  xBc       xBc ",
  "  xBc       xBc ",
  "  xBc       xBc ",
  "   xBBBBBBBBBc  ",
  "  xBc    xBBBBc ",
  "  xBc    xBBBBc ",
  "  xBc    xBBBBc ",
  "  xBc    xBBBBc ",
  "  xBBc   xBBBBc ",
  "   xBBBBBBBBBc  ",
  "                ");


const array string: nine is [](
  "                ",
  "                ",
  "   xBBBBBBBBBc  ",
  "  xBBc     xBBc ",
  "  xBc       xBc ",
  "  xBc       xBc ",
  "  xBc       xBc ",
  "  xBc       xBc ",
  "   xBBBBBBBBBBc ",
  "         xBBBBc ",
  "         xBBBBc ",
  "         xBBBBc ",
  "  xBc    xBBBBc ",
  "  xBBc   xBBBBc ",
  "   xBBBBBBBBBc  ",
  "                ");


const func cardType: genCard (in array string: pattern) is func
  result
    var cardType: aCard is cardType.value;
  begin
    aCard.picture := pattern;
  end func;


var cardType: back     is genCard(card_back_pic);

var array cardType: cards is [](
    genCard(fairy_pic),
    genCard(computer_pic),
    genCard(sea_pic),
    genCard(big_bush_pic),
    genCard(crown_pic),
    genCard(hut_pic),
    genCard(fountain_pic),
    genCard(snake_pic),
    genCard(lamp_pic),
    genCard(scepter_pic),
    genCard(book_pic),
    genCard(hourglass_pic),
    genCard(large_gem_pic),
    genCard(magic_wand_pic),
    genCard(sword_pic),
    genCard(key_pic),
    genCard(glasses_pic),
    genCard(helmet_pic),
    genCard(flask_pic),
    genCard(crystal_ball_pic),
    genCard(necklace_pic),
    genCard(holy_cross_pic),
    genCard(diamond_pic),
    genCard(silver_bars_pic),
    genCard(ruby_pic),
    genCard(jade_figurine_pic),
    genCard(harp_pic),
    genCard(goldbar_pic),
    genCard(goblet_pic),
    genCard(bat_pic),
    genCard(statue_pic),
    genCard(grating_pic),
    genCard(vampire_pic),
    genCard(ogre_pic),
    genCard(demon_pic),
    genCard(chain_pic),
    genCard(woman_pic),
    genCard(panic_monster1_pic),
    genCard(panic_monster2_pic),
    genCard(panic_monster3_pic),
    genCard(dig_right_pic),
    genCard(tree_pic)
  );

var array cardType: size_descr is [](
    genCard(size_2_5),
    genCard(size_3_4),
    genCard(size_4_4),
    genCard(size_4_5),
    genCard(size_4_6),
    genCard(size_5_6),
    genCard(size_6_6),
    genCard(size_6_7),
    genCard(size_6_8),
    genCard(size_6_10),
    genCard(size_6_12),
    genCard(size_6_14)
  );

const array array integer: size_list is [](
    [](2, 5),
    [](3, 4),
    [](4, 4),
    [](4, 5),
    [](4, 6),
    [](5, 6),
    [](6, 6),
    [](6, 7),
    [](6, 8),
    [](6, 10),
    [](6, 12),
    [](6, 14)
  );


var array array fieldType: field is 0 times 0 times fieldType.value;


const proc: draw (in integer: xPos, in integer: yPos,
    inout cardType: aCard) is func
  begin
    if aCard.pixmap = PRIMITIVE_WINDOW.value then
      rect(xPos, yPos, CARD_SIZE, CARD_SIZE, white);
      drawPattern(curr_win, xPos, yPos, aCard.picture, CARD_SIZE div length(aCard.picture), black);
      aCard.pixmap := getPixmap(xPos, yPos, CARD_SIZE, CARD_SIZE);
    else
      put(xPos, yPos, aCard.pixmap);
    end if;
  end func;


const proc: put (inout cardType: aCard, in integer: line, in integer: column) is func
  begin
    draw(LEFT_BORDER + CARD_BORDER + FIELD_SIZE * pred(column),
        UPPER_BORDER + CARD_BORDER + FIELD_SIZE * pred(line), aCard);
  end func;


const proc: prepare (inout cardType: aCard) is func
  local
    var integer: height is 0;
    var integer: width is 0;
    var integer: scale is 0;
    var PRIMITIVE_WINDOW: pixmap is PRIMITIVE_WINDOW.value;
    var integer: lin is 0;
    var integer: col is 0;
  begin
    if aCard.pixmap = PRIMITIVE_WINDOW.value then
      height := length(aCard.picture);
      width := length(aCard.picture[1]);
      scale := CARD_SIZE div height;
      pixmap := newPixmap(width * scale, height * scale);
      clear(pixmap, black);

      lin := 1;
      while lin <= height and not inputReady(KEYBOARD) do
        for col range 1 to width do
          rect(pixmap, pred(col) * scale, pred(lin) * scale,
              scale, scale, charColor(aCard.picture[lin][col], black));
        end for;
        incr(lin);
      end while;
      if not inputReady(KEYBOARD) then
        aCard.pixmap := pixmap;
      end if;
    end if;
  end func;


const proc: show (in integer: line, in integer: column) is func
  begin
    if field[line][column].visible = backSide then
      put(cards[field[line][column].cardNumber], line, column);
      field[line][column].visible := frontSide;
      field[line][column].visited := TRUE;
    end if;
  end func;


const proc: hide (in integer: line, in integer: column) is func
  begin
    if field[line][column].visible = frontSide then
      put(back, line, column);
      field[line][column].visible := backSide;
(*
      put(cards[field[line][column].cardNumber], line, column);
      rect(LEFT_BORDER + CARD_BORDER + FIELD_SIZE * pred(column),
          UPPER_BORDER + CARD_BORDER + FIELD_SIZE * pred(line), 16, 16, light_cyan);
*)
    end if;
  end func;


const proc: remove (in integer: line, in integer: column) is func
  begin
    if field[line][column].visible <> removed then
      rect(LEFT_BORDER + CARD_BORDER + FIELD_SIZE * pred(column),
          UPPER_BORDER + CARD_BORDER + FIELD_SIZE * pred(line), CARD_SIZE, CARD_SIZE, white);
      field[line][column].visible := removed;
    end if;
  end func;


const proc: hideAll is func
  local
    var integer: line is 0;
    var integer: column is 0;
  begin
    for line range 1 to length(field) do
      for column range 1 to length(field[line]) do
        hide(line, column);
      end for;
    end for;
  end func;


const proc: draw_number (in integer: xPos, in integer: yPos, in string: num_stri) is func
  local
    var integer: index is 0;
    var char: ch is ' ';
  begin
    for index range 1 to length(num_stri) do
      ch := num_stri[index];
      if ch = ' ' then
        rect(xPos + pred(index) * 32,
            yPos,
            32,
            32,
            white);
      else
        put(xPos + pred(index) * 32,
            yPos,
            digit_pixmap[ord(ch) - ord('0')]);
      end if;
    end for;
  end func;


const proc: showHit (in integer: cardNumber, in var integer: yPos, in var integer: hits) is func
  local
    const integer: xPos is OPPONENT_XPOS + 128 + 4 * CARD_BORDER + 64;
  begin
    yPos +:= CARD_BORDER;
    draw_number(OPPONENT_XPOS + 128 + 2 * CARD_BORDER, yPos + 16, succ(hits) lpad 2);
    if hits >= 21 then
      hits -:= 21;
      yPos +:= FIELD_SIZE;
    end if;
    line(xPos + 32 * hits - 1, yPos, 0, 64, white);
    draw(xPos + 32 * hits,     yPos, cards[cardNumber]);
    line(xPos + 32 * hits + 4, yPos, 0, 64, white);
    draw(xPos + 32 * hits + 5, yPos, cards[cardNumber]);
  end func;


const func integer: countCardBacks is func
  result
    var integer: count is 0;
  local
    var integer: line is 0;
    var integer: column is 0;
  begin
    for line range 1 to length(field) do
      for column range 1 to length(field[line]) do
        if field[line][column].visible = backSide then
          incr(count);
        end if;
      end for;
    end for;
  end func;


const proc: randomField (inout integer: fieldLine, inout integer: fieldColumn) is func
  local
    var integer: line is 0;
    var integer: column is 0;
    var integer: numCards is 0;
    var integer: selectedCard is 0;
  begin
    numCards := countCardBacks;
    if numCards > 0 then
      selectedCard := rand(1, numCards);
      for line range 1 to length(field) do
        for column range 1 to length(field[line]) do
          if field[line][column].visible = backSide then
            decr(selectedCard);
            if selectedCard = 0 then
              fieldLine := line;
              fieldColumn := column;
            end if;
          end if;
        end for;
      end for;
    end if;
  end func;


const proc: randomNotVisited (inout integer: fieldLine, inout integer: fieldColumn) is func
  local
    var integer: line is 0;
    var integer: column is 0;
    var integer: numCards is 0;
    var integer: selectedCard is 0;
  begin
    for line range 1 to length(field) do
      for column range 1 to length(field[line]) do
        if field[line][column].visible = backSide and
          not field[line][column].visited then
          incr(numCards);
        end if;
      end for;
    end for;
    if numCards > 0 then
      selectedCard := rand(1, numCards);
      for line range 1 to length(field) do
        for column range 1 to length(field[line]) do
          if field[line][column].visible = backSide and
              not field[line][column].visited then
            decr(selectedCard);
            if selectedCard = 0 then
              fieldLine := line;
              fieldColumn := column;
            end if;
          end if;
        end for;
      end for;
    else
      randomField(fieldLine, fieldColumn);
    end if;
  end func;


const proc: firstOfPair (inout integer: fieldLine, inout integer: fieldColumn,
    inout boolean: found) is func
  local
    var integer: line1 is 0;
    var integer: column1 is 0;
    var integer: line2 is 0;
    var integer: column2 is 0;
  begin
    found := FALSE;
    for line1 range 1 to length(field) do
      for column1 range 1 to length(field[line1]) do
        if not found and field[line1][column1].visible = backSide and
            field[line1][column1].visited then
          for column2 range succ(column1) to length(field[line1]) do
            if field[line1][column2].visible = backSide and
                field[line1][column2].visited and
                field[line1][column1].cardNumber =
                field[line1][column2].cardNumber then
              fieldLine := line1;
              fieldColumn := column1;
              found := TRUE;
            end if;
          end for;
          for line2 range succ(line1) to length(field) do
            for column2 range 1 to length(field[line1]) do
              if field[line2][column2].visible = backSide and
                  field[line2][column2].visited and
                  field[line1][column1].cardNumber =
                  field[line2][column2].cardNumber then
                fieldLine := line1;
                fieldColumn := column1;
                found := TRUE;
              end if;
            end for;
          end for;
        end if;
      end for;
    end for;
  end func;


const proc: secondOfPair (in integer: cardNumber,
    inout integer: fieldLine, inout integer: fieldColumn,
    inout boolean: found) is func
  local
    var integer: line is 0;
    var integer: column is 0;
  begin
    found := FALSE;
    for line range 1 to length(field) do
      for column range 1 to length(field[line]) do
        if field[line][column].visible = backSide and
            field[line][column].visited and
            field[line][column].cardNumber = cardNumber then
          fieldLine := line;
          fieldColumn := column;
          found := TRUE;
        end if;
      end for;
    end for;
  end func;


const proc: computerLevel0 (inout integer: line1, inout integer: column1,
    inout integer: line2, inout integer: column2) is func
  begin
    randomField(line1, column1);
    show(line1, column1);
    flushGraphic;
    wait(1 . SECONDS);
    randomField(line2, column2);
    show(line2, column2);
    flushGraphic;
    wait(1 . SECONDS);
  end func;


const proc: computerLevel1 (inout integer: line1, inout integer: column1,
    inout integer: line2, inout integer: column2) is func
  local
    var boolean: found2 is FALSE;
  begin
    randomField(line1, column1);
    show(line1, column1);
    flushGraphic;
    wait(1 . SECONDS);
    if rand(1, 5) = 1 then
      secondOfPair(field[line1][column1].cardNumber, line2, column2, found2);
    end if;
    if not found2 then
      randomField(line2, column2);
    end if;
    show(line2, column2);
    flushGraphic;
    wait(1 . SECONDS);
  end func;


const proc: computerLevel2 (inout integer: line1, inout integer: column1,
    inout integer: line2, inout integer: column2) is func
  local
    var boolean: found2 is FALSE;
  begin
    randomField(line1, column1);
    show(line1, column1);
    flushGraphic;
    wait(1 . SECONDS);
    if rand(1, 4) = 1 then
      secondOfPair(field[line1][column1].cardNumber, line2, column2, found2);
    end if;
    if not found2 then
      randomField(line2, column2);
    end if;
    show(line2, column2);
    flushGraphic;
    wait(1 . SECONDS);
  end func;


const proc: computerLevel3 (inout integer: line1, inout integer: column1,
    inout integer: line2, inout integer: column2) is func
  local
    var boolean: found2 is FALSE;
  begin
    randomField(line1, column1);
    show(line1, column1);
    flushGraphic;
    wait(1 . SECONDS);
    if rand(1, 3) = 1 then
      secondOfPair(field[line1][column1].cardNumber, line2, column2, found2);
    end if;
    if not found2 then
      randomField(line2, column2);
    end if;
    show(line2, column2);
    flushGraphic;
    wait(1 . SECONDS);
  end func;


const proc: computerLevel4 (inout integer: line1, inout integer: column1,
    inout integer: line2, inout integer: column2) is func
  local
    var boolean: found2 is FALSE;
  begin
    randomField(line1, column1);
    show(line1, column1);
    flushGraphic;
    wait(1 . SECONDS);
    if rand(1, 2) = 1 then
      secondOfPair(field[line1][column1].cardNumber, line2, column2, found2);
    end if;
    if not found2 then
      randomField(line2, column2);
    end if;
    show(line2, column2);
    flushGraphic;
    wait(1 . SECONDS);
  end func;


const proc: computerLevel5 (inout integer: line1, inout integer: column1,
    inout integer: line2, inout integer: column2) is func
  local
    var boolean: found2 is FALSE;
  begin
    randomField(line1, column1);
    show(line1, column1);
    flushGraphic;
    wait(1 . SECONDS);
    secondOfPair(field[line1][column1].cardNumber, line2, column2, found2);
    if not found2 then
      randomField(line2, column2);
    end if;
    show(line2, column2);
    flushGraphic;
    wait(1 . SECONDS);
  end func;


const proc: computerLevel6 (inout integer: line1, inout integer: column1,
    inout integer: line2, inout integer: column2) is func
  local
    var boolean: found1 is FALSE;
    var boolean: found2 is FALSE;
  begin
    if rand(1, 4) = 1 then
      firstOfPair(line1, column1, found1);
    end if;
    if not found1 then
      randomNotVisited(line1, column1);
    end if;
    show(line1, column1);
    flushGraphic;
    wait(1 . SECONDS);
    secondOfPair(field[line1][column1].cardNumber, line2, column2, found2);
    if not found2 then
      randomNotVisited(line2, column2);
    end if;
    show(line2, column2);
    flushGraphic;
    wait(1 . SECONDS);
  end func;


const proc: computerLevel7 (inout integer: line1, inout integer: column1,
    inout integer: line2, inout integer: column2) is func
  local
    var boolean: found1 is FALSE;
    var boolean: found2 is FALSE;
  begin
    if rand(1, 3) = 1 then
      firstOfPair(line1, column1, found1);
    end if;
    if not found1 then
      randomNotVisited(line1, column1);
    end if;
    show(line1, column1);
    flushGraphic;
    wait(1 . SECONDS);
    secondOfPair(field[line1][column1].cardNumber, line2, column2, found2);
    if not found2 then
      randomNotVisited(line2, column2);
    end if;
    show(line2, column2);
    flushGraphic;
    wait(1 . SECONDS);
  end func;


const proc: computerLevel8 (inout integer: line1, inout integer: column1,
    inout integer: line2, inout integer: column2) is func
  local
    var boolean: found1 is FALSE;
    var boolean: found2 is FALSE;
  begin
    if rand(1, 2) = 1 then
      firstOfPair(line1, column1, found1);
    end if;
    if not found1 then
      randomNotVisited(line1, column1);
    end if;
    show(line1, column1);
    flushGraphic;
    wait(1 . SECONDS);
    secondOfPair(field[line1][column1].cardNumber, line2, column2, found2);
    if not found2 then
      randomNotVisited(line2, column2);
    end if;
    show(line2, column2);
    flushGraphic;
    wait(1 . SECONDS);
  end func;


const proc: computerLevel9 (inout integer: line1, inout integer: column1,
    inout integer: line2, inout integer: column2) is func
  local
    var boolean: found1 is FALSE;
    var boolean: found2 is FALSE;
  begin
    firstOfPair(line1, column1, found1);
    if not found1 then
      randomNotVisited(line1, column1);
    end if;
    show(line1, column1);
    flushGraphic;
    wait(1 . SECONDS);
    secondOfPair(field[line1][column1].cardNumber, line2, column2, found2);
    if not found2 then
      randomNotVisited(line2, column2);
    end if;
    show(line2, column2);
    flushGraphic;
    wait(1 . SECONDS);
  end func;


const proc: computerTurn is func
  local
    var integer: line1 is 0;
    var integer: column1 is 0;
    var integer: line2 is 0;
    var integer: column2 is 0;
    var boolean: onTurn is TRUE;
  begin
    while countCardBacks > 0 and onTurn do
      case game.currLevel of
        when {0}: computerLevel0(line1, column1, line2, column2);
        when {1}: computerLevel1(line1, column1, line2, column2);
        when {2}: computerLevel2(line1, column1, line2, column2);
        when {3}: computerLevel3(line1, column1, line2, column2);
        when {4}: computerLevel4(line1, column1, line2, column2);
        when {5}: computerLevel5(line1, column1, line2, column2);
        when {6}: computerLevel6(line1, column1, line2, column2);
        when {7}: computerLevel7(line1, column1, line2, column2);
        when {8}: computerLevel8(line1, column1, line2, column2);
        when {9}: computerLevel9(line1, column1, line2, column2);
        otherwise: computerLevel0(line1, column1, line2, column2);
      end case;
      if field[line1][column1].cardNumber =
          field[line2][column2].cardNumber then
        remove(line1, column1);
        remove(line2, column2);
        showHit(field[line1][column1].cardNumber, COMPUTER_HIT_YPOS, game.computerHits);
        incr(game.computerHits);
      else
        hide(line1, column1);
        hide(line2, column2);
        onTurn := FALSE;
      end if;
    end while;
  end func;


const proc: checkHit (in integer: line1, in integer: column1,
    in integer: line2, in integer: column2, inout boolean: hit) is func
  begin
    if field[line1][column1].cardNumber =
        field[line2][column2].cardNumber then
      remove(line1, column1);
      remove(line2, column2);
      showHit(field[line1][column1].cardNumber, game.player_hit_ypos, game.playerHits);
      incr(game.playerHits);
      hit := TRUE;
    else
      hide(line1, column1);
      hide(line2, column2);
    end if;
  end func;


const proc: mouseCommand (inout integer: line, inout integer: column,
    inout integer: openCards) is func
  begin
    line := clickedYPos(KEYBOARD);
    column := clickedXPos(KEYBOARD);
    if line >= UPPER_BORDER and column >= LEFT_BORDER then
      line := (line - UPPER_BORDER) div FIELD_SIZE + 1;
      column := (column - LEFT_BORDER) div FIELD_SIZE + 1;
      if line >= 1 and line <= length(field) and
          column >= 1 and column <= length(field[line]) then
        if field[line][column].visible = backSide then
          show(line, column);
          incr(openCards);
        end if;
      end if;
    end if;
  end func;


const proc: playerMove (inout boolean: hit) is func
  local
    var integer: openCards is 0;
    var integer: line1 is 0;
    var integer: column1 is 0;
    var integer: line2 is 0;
    var integer: column2 is 0;
    var boolean: moveFinished is FALSE;
    var char: command is ' ';
  begin
    hit := FALSE;
    repeat
      command := getc(KEYBOARD);
      if upper(command) = 'Q' or command = KEY_CLOSE then
        moveFinished := TRUE;
        game.quit := TRUE;
      elsif command = KEY_ESC then
        bossMode(game.quit);
        if game.quit then
          moveFinished := TRUE;
        end if;
      elsif command in digit_char then
        game.currLevel := ord(command) - ord('0');
        put(OPPONENT_XPOS - 40, OPPONENT_YPOS, digit_pixmap[game.currLevel]);
      elsif command in {KEY_RIGHT, KEY_UP} then
        if game.currLevel < 9 then
          incr(game.currLevel);
          put(OPPONENT_XPOS - 40, OPPONENT_YPOS, digit_pixmap[game.currLevel]);
        end if;
      elsif command in {KEY_LEFT, KEY_DOWN} then
        if game.currLevel > 0 then
          decr(game.currLevel);
          put(OPPONENT_XPOS - 40, OPPONENT_YPOS, digit_pixmap[game.currLevel]);
        end if;
      elsif openCards = 2 then
        checkHit(line1, column1, line2, column2, hit);
        moveFinished := TRUE;
      elsif command = KEY_MOUSE1 then
        if openCards = 0 then
          mouseCommand(line1, column1, openCards);
        elsif openCards = 1 then
          mouseCommand(line2, column2, openCards);
        end if;
      elsif command not in {KEY_MOUSE2, KEY_MOUSE3, KEY_MOUSE4, KEY_MOUSE5} then
        hideAll;
        moveFinished := TRUE;
      end if;
    until moveFinished;
  end func;


const proc: playerTurn is func
  local
    var boolean: hit is TRUE;
  begin
    while countCardBacks > 0 and hit do
      playerMove(hit);
    end while;
  end func;


const proc: dealCards (in integer: field_lines, in integer: field_columns) is func
  local
    var integer: line is 0;
    var integer: column is 0;
    var integer: cardNumber is 0;
  begin
    field := field_lines times field_columns times fieldType.value;
    for line range 1 to field_lines do
      for column range 1 to field_columns do
        put(back, line, column);
        repeat
          cardNumber := rand(1, field_lines * field_columns div 2);
        until cards[cardNumber].number < 2;
        field[line][column].cardNumber := cardNumber;
        incr(cards[cardNumber].number);
      end for;
    end for;
    game.player_hit_ypos := UPPER_BORDER + field_lines * FIELD_SIZE - CARD_BORDER + COMPUTER_HIT_YPOS;
  end func;


const proc: selectSize is func
  local
    var integer: index is 0;
    var char: command is ' ';
    var integer: line is 0;
    var integer: column is 0;
    var boolean: selected is FALSE;
  begin
    for index range 1 to length(size_descr) do
      put(size_descr[index], 1, index);
    end for;
    repeat
      command := getc(KEYBOARD);
      if upper(command) = 'Q' or command = KEY_CLOSE then
        selected := TRUE;
        game.quit := TRUE;
      elsif command = KEY_ESC then
        bossMode(game.quit);
        if game.quit then
          selected := TRUE;
        end if;
      elsif command = KEY_MOUSE1 then
        line := clickedYPos(KEYBOARD);
        column := clickedXPos(KEYBOARD);
        if line >= UPPER_BORDER and column >= LEFT_BORDER then
          line := (line - UPPER_BORDER) div FIELD_SIZE + 1;
          column := (column - LEFT_BORDER) div FIELD_SIZE + 1;
          if line = 1 and column >= 1 and column <= length(size_descr) then
            clear(curr_win, white);
            put(OPPONENT_XPOS, OPPONENT_YPOS, opponent);
            dealCards(size_list[column][1], size_list[column][2]);
            selected := TRUE;
          end if;
        end if;
      end if;
    until selected;
  end func;


const proc: main is func
  local
    var text: scr is STD_NULL;
    var boolean: done is FALSE;
    var char: command is ' ';
    var integer: line is 0;
    var integer: column is 0;
    var integer: index is 0;
  begin
    screen(WINDOW_WIDTH, WINDOW_HEIGHT);
    selectInput(curr_win, KEY_CLOSE, TRUE);
    clear(curr_win, white);
    scr := openPixmapFontFile(curr_win, 250, 0);
    setFont(scr, stdFont9);
    color(scr, black, white);
    writeln(scr);
    writeln(scr, "P A I R S   -   Concentration game");
    writeln(scr);
    writeln(scr, "Copyright (C) 2005  Thomas Mertes");
    writeln(scr);
    writeln(scr, "This program is free software under the terms of the GNU General Public License.");
    writeln(scr);
    writeln(scr, "Pairs is written in the Seed7 programming language");
    writeln(scr, "Homepage:    http://seed7.sourceforge.net");
    KEYBOARD := GRAPH_KEYBOARD;
    digit_pixmap := [0](
      createPixmap(zero,  2, black),
      createPixmap(one,   2, black),
      createPixmap(two,   2, black),
      createPixmap(three, 2, black),
      createPixmap(four,  2, black),
      createPixmap(five,  2, black),
      createPixmap(six,   2, black),
      createPixmap(seven, 2, black),
      createPixmap(eight, 2, black),
      createPixmap(nine,  2, black));

    opponent := createPixmap(woman_pic, 2, black);
    put(OPPONENT_XPOS, OPPONENT_YPOS, opponent);

    selectSize;

    put(OPPONENT_XPOS - 40, OPPONENT_YPOS, digit_pixmap[game.currLevel]);

    index := 1;
    while countCardBacks > 0 and not game.quit do
      while index <= length(cards) and not inputReady(KEYBOARD) do
        prepare(cards[index]);
        if not inputReady(KEYBOARD) then
          (* writeln(index); *)
          incr(index);
        end if;
      end while;
      playerTurn;
      if not game.quit then
        computerTurn;
      end if;
    end while;
    if not game.quit then
      command := getc(KEYBOARD);
    end if;
  end func;