Advertisement
Guest User

Nibbles BAS (Tergiver)

a guest
Oct 14th, 2010
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 37.65 KB | None | 0 0
  1. using System;
  2. using System.Linq;
  3. using System.Text;
  4. using System.Threading;
  5. using System.ComponentModel;
  6. using System.Runtime.InteropServices;
  7.  
  8. namespace Nibbles.Bas
  9. {
  10.     public struct SnakeBody
  11.     {
  12.         public int row, col;
  13.     }
  14.  
  15.     /// <summary>This type defines the player's snake</summary>
  16.     public struct SnakeType
  17.     {
  18.         public int head;
  19.         public int length;
  20.         public int row;
  21.         public int col;
  22.         public int direction;
  23.         public int lives;
  24.         public int score;
  25.         public int scolor;
  26.         public bool alive;
  27.     }
  28.  
  29.     /// <summary>
  30.     /// This type is used to represent the playing screen in memory
  31.     /// It is used to simulate graphics in text mode, and has some interesting,
  32.     /// and slightly advanced methods to increasing the speed of operation.
  33.     /// Instead of the normal 80x25 text graphics using chr$(219) "█", we will be
  34.     /// using chr$(220)"▄" and chr$(223) "▀" and chr$(219) "█" to mimic an 80x50
  35.     /// pixel screen.
  36.     /// Check out sub-programs SET and POINTISTHERE to see how this is implemented
  37.     /// feel free to copy these (as well as arenaType and the DIM ARENA stmt and the
  38.     /// initialization code in the DrawScreen subprogram) and use them in your own
  39.     /// programs
  40.     /// </summary>
  41.     public struct ArenaType
  42.     {
  43.         /// <summary>Maps the 80x50 point into the real 80x25</summary>
  44.         public int realRow;
  45.         /// <summary>Stores the current color of the point</summary>
  46.         public int acolor;
  47.         /// <summary>Each char has 2 points in it.  .SISTER is -1 if sister point is above, +1 if below</summary>
  48.         public int sister;
  49.     }
  50.  
  51.     public static class Program
  52.     {
  53.         // Constants
  54.         public const int MAXSNAKELENGTH = 1000;
  55.         public const int STARTOVER = 1;     // Parameters to 'Level' SUB
  56.         public const int SAMELEVEL = 2;
  57.         public const int NEXTLEVEL = 3;
  58.  
  59.         // Global variables
  60.         public static ArenaType[,] arena = new ArenaType[51, 81]; // (1 TO 50, 1 TO 80)
  61.         public static int curLevel;
  62.         public static int[] colorTable = new int[10]; // (10)
  63.  
  64.         public static Random Rnd;
  65.  
  66.         static int originalWindowWidth, originalWindowHeight;
  67.  
  68.         public static void Main(string[] args)
  69.         {
  70.             originalWindowWidth = Console.WindowWidth;
  71.             originalWindowHeight = Console.WindowHeight;
  72.  
  73.             try
  74.             {
  75.                 bool isTrueTypeFont = ConsoleHelper.IsOutputConsoleFontTrueType();
  76.                 InitStrings(isTrueTypeFont);
  77.  
  78.                 Console.Title = String.Format("Nibbles BAS [{0}]", isTrueTypeFont ? "TRUE TYPE" : "RASTER");
  79.                 Console.OutputEncoding = isTrueTypeFont ? Encoding.UTF8 : Encoding.Default;
  80.                 Console.SetWindowSize(80, 25);
  81.                 Console.CursorVisible = false;
  82.                 Console.CancelKeyPress += (s, e) => RestoreConsole();
  83.  
  84.                 Rnd = new Random();
  85.                 // ClearKeyLocks();
  86.                 Intro();
  87.                 int NumPlayers, speed;
  88.                 string diff, monitor;
  89.                 GetInputs(out NumPlayers, out speed, out diff, out monitor);
  90.                 SetColors(monitor);
  91.                 DrawScreen();
  92.  
  93.                 do
  94.                     PlayNibbles(NumPlayers, speed, diff);
  95.                 while (StillWantsToPlay());
  96.  
  97.                 RestoreConsole();
  98.             }
  99.             catch (Exception ex)
  100.             {
  101.                 RestoreConsole();
  102.                 Console.WriteLine(ex);
  103.             }
  104.         }
  105.  
  106.         private static void RestoreConsole()
  107.         {
  108.             Console.ResetColor();
  109.             Console.CursorVisible = true;
  110.             Console.SetWindowSize(originalWindowWidth, originalWindowHeight);
  111.             Console.Clear();
  112.         }
  113.  
  114.         static char BlockChar;
  115.         static char BlockUpperChar;
  116.         static char BlockLowerChar;
  117.         static string SpacePauseUpperLine;
  118.         static string SpacePauseLowerLine;
  119.         static string WelcomeHelpLine1, WelcomeHelpLine2, WelcomeHelpLine3;
  120.         static string GameOverLine1, GameOverLine2, GameOverLine3, GameOverLine4, GameOverLine5;
  121.  
  122.         private static void InitStrings(bool isTrueTypeFont)
  123.         {
  124.             if (isTrueTypeFont)
  125.             {
  126.                 BlockChar = '█';
  127.                 BlockUpperChar = '▀';
  128.                 BlockLowerChar = '▄';
  129.                 SpacePauseUpperLine = "█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█";
  130.                 SpacePauseLowerLine = "█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█";
  131.                 WelcomeHelpLine1 = "P - Pause                ↑                      W       ";
  132.                 WelcomeHelpLine2 = "                     (Left) ←   → (Right)   (Left) A   D (Right)  ";
  133.                 WelcomeHelpLine3 = "                         ↓                      S       ";
  134.                 GameOverLine1 = "█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█";
  135.                 GameOverLine2 = "█       G A M E   O V E R       █";
  136.                 GameOverLine3 = "█                               █";
  137.                 GameOverLine4 = "█      Play Again?   (Y/N)      █";
  138.                 GameOverLine5 = "█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█";
  139.             }
  140.             else
  141.             {
  142.                 BlockChar = (char)219;
  143.                 BlockUpperChar = (char)223;
  144.                 BlockLowerChar = (char)220;
  145.                 SpacePauseUpperLine = new String(BlockChar, 1) + new String(BlockUpperChar, 31) + new String(BlockChar, 1);
  146.                 SpacePauseLowerLine = new String(BlockChar, 1) + new String(BlockLowerChar, 31) + new String(BlockChar, 1);
  147.                 // There isn't a good set of symbols for arrows in 8-bit ASCII so I just left them out
  148.                 WelcomeHelpLine1 = "P - Pause                                       W       ";
  149.                 WelcomeHelpLine2 = "                     (Left)       (Right)   (Left) A   D (Right)  ";
  150.                 WelcomeHelpLine3 = "                                                S       ";
  151.                 GameOverLine1 = SpacePauseUpperLine;
  152.                 GameOverLine2 = new String(BlockChar, 1) + "       G A M E   O V E R       " + new String(BlockChar, 1);
  153.                 GameOverLine3 = new String(BlockChar, 1) + new String(' ', 31) + new String(BlockChar, 1);
  154.                 GameOverLine4 = new String(BlockChar, 1) + "      Play Again?   (Y/N)      " + new String(BlockChar, 1);
  155.                 GameOverLine5 = SpacePauseLowerLine;
  156.             }
  157.         }
  158.  
  159.         private static void SetColors(string monitor)
  160.         {
  161.             if (monitor == "M")
  162.                 colorTable = new[] { 15, 7, 7, 0, 15, 0 };
  163.             else
  164.                 colorTable = new[] { 14, 13, 12, 1, 15, 4 };
  165.         }
  166.  
  167.         /// <summary>Centers text on given row</summary>
  168.         private static void Center(int row, string text)
  169.         {
  170.             ConsoleSetCursorPosition(41 - text.Length / 2, row);
  171.             Console.Write(text);
  172.         }
  173.  
  174.         /// <summary>Draws playing field</summary>
  175.         private static void DrawScreen()
  176.         {
  177.             // initialize screen
  178.             // VIEW PRINT (?)
  179.             Console.ForegroundColor = (ConsoleColor)colorTable[0];
  180.             Console.BackgroundColor = (ConsoleColor)colorTable[3];
  181.             Console.Clear();
  182.  
  183.             // Print title & message
  184.             Center(1, "Nibbles!");
  185.             Center(11, "Initializing Playing Field...");
  186.  
  187.             // Initialize arena array
  188.             for (int row = 1; row <= 50; row++)
  189.                 for (int col = 1; col <= 80; col++)
  190.                     arena[row, col] = new ArenaType { realRow = (row + 1) / 2, sister = (row % 2) * 2 - 1 };
  191.         }
  192.  
  193.         /// <summary>Erases snake to facilitate moving through playing field</summary>
  194.         private static void EraseSnake(SnakeType[] snake, SnakeBody[,] snakeBod, int snakeNum)
  195.         {
  196.             for (int c = 0; c < 9; c++)
  197.                 for (int b = snake[snakeNum].length - c; b >= 0; b -= 10)
  198.                 {
  199.                     var tail = (snake[snakeNum].head + MAXSNAKELENGTH - b) % MAXSNAKELENGTH;
  200.                     Set(snakeBod[tail, snakeNum].row, snakeBod[tail, snakeNum].col, colorTable[3]);
  201.                     Thread.Sleep(2);
  202.                 }
  203.         }
  204.  
  205.         /// <summary>Gets player inputs</summary>
  206.         private static void GetInputs(out int NumPlayers, out int speed, out string diff, out string monitor)
  207.         {
  208.             Console.ForegroundColor = ConsoleColor.Gray;
  209.             Console.BackgroundColor = ConsoleColor.Black;
  210.             Console.Clear();
  211.             Console.CursorVisible = true;
  212.  
  213.             bool success;
  214.             do
  215.             {
  216.                 ConsoleSetCursorPosition(47, 5);
  217.                 Console.Write(new string(' ', 34));
  218.                 ConsoleSetCursorPosition(20, 5);
  219.                 Console.Write("How many players (1 or 2)");
  220.                 string num = Console.ReadLine();
  221.                 success = int.TryParse(num, out NumPlayers);
  222.             }
  223.             while (!success || NumPlayers < 1 || NumPlayers > 2);
  224.  
  225.             ConsoleSetCursorPosition(21, 8);
  226.             Console.Write("Skill level (1 to 100)");
  227.             ConsoleSetCursorPosition(22, 9);
  228.             Console.Write("1   = Novice");
  229.             ConsoleSetCursorPosition(22, 10);
  230.             Console.Write("90  = Expert");
  231.             ConsoleSetCursorPosition(22, 11);
  232.             Console.Write("100 = Twiddle Fingers");
  233.             ConsoleSetCursorPosition(15, 12);
  234.             Console.Write("(Computer speed may affect your skill level)");
  235.  
  236.             do
  237.             {
  238.                 ConsoleSetCursorPosition(44, 8);
  239.                 Console.Write(new string(' ', 35));
  240.                 ConsoleSetCursorPosition(43, 8);
  241.                 string gamespeed = Console.ReadLine();
  242.                 success = int.TryParse(gamespeed, out speed);
  243.             }
  244.             while (!success || speed < 1 || speed > 100);
  245.  
  246.             speed = (100 - speed) * 2 + 1;
  247.  
  248.             do
  249.             {
  250.                 ConsoleSetCursorPosition(56, 15);
  251.                 Console.Write(new string(' ', 25));
  252.                 ConsoleSetCursorPosition(15, 15);
  253.                 Console.Write("Increase game speed during play (Y or N)");
  254.                 diff = Console.ReadLine().ToUpperInvariant();
  255.             }
  256.             while (diff != "Y" && diff != "N");
  257.  
  258.             do
  259.             {
  260.                 ConsoleSetCursorPosition(46, 17);
  261.                 Console.Write(new string(' ', 34));
  262.                 ConsoleSetCursorPosition(17, 17);
  263.                 Console.Write("Monochrome or color monitor (M or C)");
  264.                 monitor = Console.ReadLine().ToUpperInvariant();
  265.             }
  266.             while (monitor != "M" && monitor != "C");
  267.  
  268.             Console.CursorVisible = false;
  269.         }
  270.  
  271.         /// <summary>Initializes playing field colors</summary>
  272.         private static void InitColors()
  273.         {
  274.             for (int row = 1; row <= 50; row++)
  275.                 for (int col = 1; col <= 80; col++)
  276.                     arena[row, col].acolor = colorTable[3];
  277.  
  278.             Console.Clear();
  279.  
  280.             // Set (turn on) pixels for screen border
  281.             for (int col = 1; col <= 80; col++)
  282.             {
  283.                 Set(3, col, colorTable[2]);
  284.                 Set(50, col, colorTable[2]);
  285.             }
  286.             for (int row = 4; row <= 49; row++)
  287.             {
  288.                 Set(row, 1, colorTable[2]);
  289.                 Set(row, 80, colorTable[2]);
  290.             }
  291.         }
  292.  
  293.         /// <summary>Displays game introduction</summary>
  294.         private static void Intro()
  295.         {
  296.             Console.ForegroundColor = (ConsoleColor)15;
  297.             Console.BackgroundColor = (ConsoleColor)0;
  298.             Console.Clear();
  299.  
  300.             Center(4, "Q B a s i c   N i b b l e s");
  301.             Console.ForegroundColor = (ConsoleColor)7;
  302.             Center(6, "Copyright (C) Microsoft Corporation 1990");
  303.             Center(8, "Nibbles is a game for one or two players.  Navigate your snakes");
  304.             Center(9, "around the game board trying to eat up numbers while avoiding");
  305.             Center(10, "running into walls or other snakes.  The more numbers you eat up,");
  306.             Center(11, "the more points you gain and the longer your snake becomes.");
  307.             Center(13, " Game Controls ");
  308.             Center(15, "  General             Player 1               Player 2    ");
  309.             Center(16, "                        (Up)                   (Up)      ");
  310.             Center(17, WelcomeHelpLine1);
  311.             Center(18, WelcomeHelpLine2);
  312.             Center(19, WelcomeHelpLine3);
  313.             Center(20, "                       (Down)                 (Down)     ");
  314.             Center(24, "Press any key to continue");
  315.  
  316.             // PLAY "MBT160O1L8CDEDCDL4ECC"
  317.             SparklePause();
  318.         }
  319.  
  320.         /// <summary>Sets game level</summary>
  321.         private static void Level(int WhatToDO, SnakeType[] sammy)
  322.         {
  323.             switch (WhatToDO)
  324.             {
  325.                 case STARTOVER:
  326.                     curLevel = 1;
  327.                     break;
  328.  
  329.                 case NEXTLEVEL:
  330.                     curLevel = curLevel + 1;
  331.                     break;
  332.             }
  333.  
  334.             // Initialize Snakes
  335.             sammy[0].head = 1;
  336.             sammy[0].length = 2;
  337.             sammy[0].alive = true;
  338.             sammy[1].head = 1;
  339.             sammy[1].length = 2;
  340.             sammy[1].alive = true;
  341.  
  342.             InitColors();
  343.  
  344.             switch (curLevel)
  345.             {
  346.                 case 1:
  347.                     sammy[0].row = 25;
  348.                     sammy[1].row = 25;
  349.                     sammy[0].col = 50;
  350.                     sammy[1].col = 30;
  351.                     sammy[0].direction = 4;
  352.                     sammy[1].direction = 3;
  353.                     break;
  354.  
  355.                 case 2:
  356.                     for (int i = 20; i <= 60; i++)
  357.                         Set(25, i, colorTable[2]);
  358.                     sammy[0].row = 7;
  359.                     sammy[1].row = 43;
  360.                     sammy[0].col = 60;
  361.                     sammy[1].col = 20;
  362.                     sammy[0].direction = 3;
  363.                     sammy[1].direction = 4;
  364.                     break;
  365.  
  366.                 case 3:
  367.                     for (int i = 10; i <= 40; i++)
  368.                     {
  369.                         Set(i, 20, colorTable[2]);
  370.                         Set(i, 60, colorTable[2]);
  371.                     }
  372.                     sammy[0].row = 25;
  373.                     sammy[1].row = 25;
  374.                     sammy[0].col = 50;
  375.                     sammy[1].col = 30;
  376.                     sammy[0].direction = 1;
  377.                     sammy[1].direction = 2;
  378.                     break;
  379.  
  380.                 case 4:
  381.                     for (int i = 4; i <= 30; i++)
  382.                     {
  383.                         Set(i, 20, colorTable[2]);
  384.                         Set(53 - i, 60, colorTable[2]);
  385.                     }
  386.                     for (int i = 2; i <= 40; i++)
  387.                     {
  388.                         Set(38, i, colorTable[2]);
  389.                         Set(15, 81 - i, colorTable[2]);
  390.                     }
  391.                     sammy[0].row = 7;
  392.                     sammy[1].row = 43;
  393.                     sammy[0].col = 60;
  394.                     sammy[1].col = 20;
  395.                     sammy[0].direction = 3;
  396.                     sammy[1].direction = 4;
  397.                     break;
  398.  
  399.                 case 5:
  400.                     for (int i = 13; i <= 39; i++)
  401.                     {
  402.                         Set(i, 21, colorTable[2]);
  403.                         Set(i, 59, colorTable[2]);
  404.                     }
  405.                     for (int i = 23; i <= 57; i++)
  406.                     {
  407.                         Set(11, i, colorTable[2]);
  408.                         Set(41, i, colorTable[2]);
  409.                     }
  410.                     sammy[0].row = 25;
  411.                     sammy[1].row = 25;
  412.                     sammy[0].col = 50;
  413.                     sammy[1].col = 30;
  414.                     sammy[0].direction = 1;
  415.                     sammy[1].direction = 2;
  416.                     break;
  417.  
  418.                 case 6:
  419.                     for (int i = 4; i <= 49; i++)
  420.                     {
  421.                         if (i > 30 || i < 23)
  422.                         {
  423.                             Set(i, 10, colorTable[2]);
  424.                             Set(i, 20, colorTable[2]);
  425.                             Set(i, 30, colorTable[2]);
  426.                             Set(i, 40, colorTable[2]);
  427.                             Set(i, 50, colorTable[2]);
  428.                             Set(i, 60, colorTable[2]);
  429.                             Set(i, 70, colorTable[2]);
  430.                         }
  431.                     }
  432.                     sammy[0].row = 7;
  433.                     sammy[1].row = 43;
  434.                     sammy[0].col = 65;
  435.                     sammy[1].col = 15;
  436.                     sammy[0].direction = 2;
  437.                     sammy[1].direction = 1;
  438.                     break;
  439.  
  440.                 case 7:
  441.                     for (int i = 4; i <= 49; i += 2)
  442.                         Set(i, 40, colorTable[2]);
  443.                     sammy[0].row = 7;
  444.                     sammy[1].row = 43;
  445.                     sammy[0].col = 65;
  446.                     sammy[1].col = 15;
  447.                     sammy[0].direction = 2;
  448.                     sammy[1].direction = 1;
  449.                     break;
  450.  
  451.                 case 8:
  452.                     for (int i = 4; i <= 40; i++)
  453.                     {
  454.                         Set(i, 10, colorTable[2]);
  455.                         Set(53 - i, 20, colorTable[2]);
  456.                         Set(i, 30, colorTable[2]);
  457.                         Set(53 - i, 40, colorTable[2]);
  458.                         Set(i, 50, colorTable[2]);
  459.                         Set(53 - i, 60, colorTable[2]);
  460.                         Set(i, 70, colorTable[2]);
  461.                     }
  462.                     sammy[0].row = 7;
  463.                     sammy[1].row = 43;
  464.                     sammy[0].col = 65;
  465.                     sammy[1].col = 15;
  466.                     sammy[0].direction = 2;
  467.                     sammy[1].direction = 1;
  468.                     break;
  469.  
  470.                 case 9:
  471.                     for (int i = 6; i <= 47; i++)
  472.                     {
  473.                         Set(i, i, colorTable[2]);
  474.                         Set(i, i + 28, colorTable[2]);
  475.                     }
  476.                     sammy[0].row = 40;
  477.                     sammy[1].row = 15;
  478.                     sammy[0].col = 75;
  479.                     sammy[1].col = 5;
  480.                     sammy[0].direction = 1;
  481.                     sammy[1].direction = 2;
  482.                     break;
  483.  
  484.                 default:
  485.                     for (int i = 4; i <= 49; i += 2)
  486.                     {
  487.                         Set(i, 10, colorTable[2]);
  488.                         Set(i + 1, 20, colorTable[2]);
  489.                         Set(i, 30, colorTable[2]);
  490.                         Set(i + 1, 40, colorTable[2]);
  491.                         Set(i, 50, colorTable[2]);
  492.                         Set(i + 1, 60, colorTable[2]);
  493.                         Set(i, 70, colorTable[2]);
  494.                     }
  495.                     sammy[0].row = 7;
  496.                     sammy[1].row = 43;
  497.                     sammy[0].col = 65;
  498.                     sammy[1].col = 15;
  499.                     sammy[0].direction = 2;
  500.                     sammy[1].direction = 1;
  501.                     break;
  502.             }
  503.         }
  504.  
  505.         /// <summary>Main routine that controls game play</summary>
  506.         private static void PlayNibbles(int NumPlayers, int speed, string diff)
  507.         {
  508.             // Initialize Snakes
  509.             SnakeBody[,] sammyBody = new SnakeBody[MAXSNAKELENGTH, 2];
  510.             SnakeType[] sammy = new SnakeType[2];
  511.             sammy[0] = new SnakeType { lives = 5, score = 0, scolor = colorTable[0] };
  512.             sammy[1] = new SnakeType { lives = 5, score = 0, scolor = colorTable[1] };
  513.  
  514.             Level(STARTOVER, sammy);
  515.             var startRow1 = sammy[0].row;
  516.             var startCol1 = sammy[0].col;
  517.             var startRow2 = sammy[1].row;
  518.             var startCol2 = sammy[1].col;
  519.  
  520.             var curSpeed = speed;
  521.  
  522.             // play Nibbles until finished
  523.  
  524.             SpacePause("     Level " + curLevel + ",  Push Space");
  525.  
  526.             do
  527.             {
  528.                 if (NumPlayers == 1)
  529.                     sammy[1].row = 0;
  530.  
  531.                 var number = 1; // Current number that snakes are trying to run into
  532.                 var nonum = true; // nonum = TRUE if a number is not on the screen
  533.                 int numberRow = 0, NumberCol = 0, sisterRow = 0;
  534.  
  535.                 var playerDied = false;
  536.                 PrintScore(NumPlayers, sammy[0].score, sammy[1].score, sammy[0].lives, sammy[1].lives);
  537.                 // PLAY "T160O1>L20CDEDCDL10ECC"
  538.  
  539.                 do
  540.                 {
  541.                     // Print number if no number exists
  542.                     if (nonum)
  543.                     {
  544.                         do
  545.                         {
  546.                             numberRow = (int)(Rnd.NextDouble() * 47 + 3);
  547.                             NumberCol = (int)(Rnd.NextDouble() * 78 + 2);
  548.                             sisterRow = numberRow + arena[numberRow, NumberCol].sister;
  549.                         }
  550.                         while (PointIsThere(numberRow, NumberCol, colorTable[3]) || PointIsThere(sisterRow, NumberCol, colorTable[3]));
  551.                         numberRow = arena[numberRow, NumberCol].realRow;
  552.                         nonum = false;
  553.                         Console.ForegroundColor = (ConsoleColor)colorTable[0];
  554.                         Console.BackgroundColor = (ConsoleColor)colorTable[3];
  555.                         ConsoleSetCursorPosition(NumberCol, numberRow);
  556.                         Console.Write(number.ToString().Last());
  557.                     }
  558.  
  559.                     // Delay game
  560.                     Thread.Sleep(curSpeed);
  561.  
  562.                     // Get keyboard input & Change direction accordingly
  563.                     if (Console.KeyAvailable)
  564.                     {
  565.                         var kbd = Console.ReadKey(true).Key;
  566.                         switch (kbd)
  567.                         {
  568.                             case ConsoleKey.W: if (sammy[1].direction != 2) sammy[1].direction = 1; break;
  569.                             case ConsoleKey.S: if (sammy[1].direction != 1) sammy[1].direction = 2; break;
  570.                             case ConsoleKey.A: if (sammy[1].direction != 4) sammy[1].direction = 3; break;
  571.                             case ConsoleKey.D: if (sammy[1].direction != 3) sammy[1].direction = 4; break;
  572.                             case ConsoleKey.UpArrow: if (sammy[0].direction != 2) sammy[0].direction = 1; break;
  573.                             case ConsoleKey.DownArrow: if (sammy[0].direction != 1) sammy[0].direction = 2; break;
  574.                             case ConsoleKey.LeftArrow: if (sammy[0].direction != 4) sammy[0].direction = 3; break;
  575.                             case ConsoleKey.RightArrow: if (sammy[0].direction != 3) sammy[0].direction = 4; break;
  576.                             case ConsoleKey.Spacebar: case ConsoleKey.P: SpacePause(" Game Paused ... Push Space  "); break;
  577.                             default: break;
  578.                         }
  579.                     }
  580.  
  581.                     for (int a = 0; a < NumPlayers; a++)
  582.                     {
  583.                         // Move Snake
  584.                         switch (sammy[a].direction)
  585.                         {
  586.                             case 1: sammy[a].row = sammy[a].row - 1; break;
  587.                             case 2: sammy[a].row = sammy[a].row + 1; break;
  588.                             case 3: sammy[a].col = sammy[a].col - 1; break;
  589.                             case 4: sammy[a].col = sammy[a].col + 1; break;
  590.                         }
  591.  
  592.                         // If snake hits number, respond accordingly
  593.                         if (numberRow == (sammy[a].row + 1) / 2 && NumberCol == sammy[a].col)
  594.                         {
  595.                             // PLAY "MBO0L16>CCCE"
  596.                             if (sammy[a].length < MAXSNAKELENGTH - 30)
  597.                                 sammy[a].length = sammy[a].length + number * 4;
  598.  
  599.                             sammy[a].score = sammy[a].score + number;
  600.                             PrintScore(NumPlayers, sammy[0].score, sammy[1].score, sammy[0].lives, sammy[1].lives);
  601.                             number = number + 1;
  602.                             if (number == 10)
  603.                             {
  604.                                 EraseSnake(sammy, sammyBody, 0);
  605.                                 EraseSnake(sammy, sammyBody, 1);
  606.                                 ConsoleSetCursorPosition(NumberCol, numberRow);
  607.                                 Console.Write(" ");
  608.                                 Level(NEXTLEVEL, sammy);
  609.                                 PrintScore(NumPlayers, sammy[0].score, sammy[1].score, sammy[0].lives, sammy[1].lives);
  610.                                 SpacePause("     Level " + curLevel + ",  Push Space");
  611.                                 if (NumPlayers == 1)
  612.                                     sammy[1].row = 0;
  613.                                 number = 1;
  614.                                 if (diff == "P")
  615.                                 {
  616.                                     speed = speed - 10;
  617.                                     curSpeed = speed;
  618.                                 }
  619.                             }
  620.                             nonum = true;
  621.                             if (curSpeed < 1)
  622.                                 curSpeed = 1;
  623.                         }
  624.                     }
  625.  
  626.                     for (int a = 0; a < NumPlayers; a++)
  627.                     {
  628.                         // If player runs into any point, or the head of the other snake, it dies.
  629.                         if (PointIsThere(sammy[a].row, sammy[a].col, colorTable[3]) || (sammy[0].row == sammy[1].row && sammy[0].col == sammy[1].col))
  630.                         {
  631.                             // PLAY "MBO0L32EFGEFDC"
  632.                             Console.BackgroundColor = (ConsoleColor)colorTable[3];
  633.                             ConsoleSetCursorPosition(NumberCol, numberRow);
  634.                             Console.Write(" ");
  635.                             playerDied = true;
  636.                             sammy[a].alive = false;
  637.                             sammy[a].lives = sammy[a].lives - 1;
  638.                         }
  639.                         // Otherwise, move the snake, and erase the tail
  640.                         else
  641.                         {
  642.                             sammy[a].head = (sammy[a].head + 1) % MAXSNAKELENGTH;
  643.                             sammyBody[sammy[a].head, a].row = sammy[a].row;
  644.                             sammyBody[sammy[a].head, a].col = sammy[a].col;
  645.                             var tail = (sammy[a].head + MAXSNAKELENGTH - sammy[a].length) % MAXSNAKELENGTH;
  646.                             Set(sammyBody[tail, a].row, sammyBody[tail, a].col, colorTable[3]);
  647.                             sammyBody[tail, a].row = 0;
  648.                             Set(sammy[a].row, sammy[a].col, sammy[a].scolor);
  649.                         }
  650.                     }
  651.                 }
  652.                 while (!playerDied);
  653.  
  654.                 // reset speed to initial value
  655.                 curSpeed = speed;
  656.  
  657.                 for (int a = 0; a < NumPlayers; a++)
  658.                 {
  659.                     EraseSnake(sammy, sammyBody, a);
  660.  
  661.                     // If dead, then erase snake in really cool way
  662.                     if (!sammy[a].alive)
  663.                     {
  664.                         // Update score
  665.                         sammy[a].score = sammy[a].score - 10;
  666.                         PrintScore(NumPlayers, sammy[0].score, sammy[1].score, sammy[0].lives, sammy[1].lives);
  667.  
  668.                         if (a == 0)
  669.                             SpacePause(" Sammy Dies! Push Space! --->");
  670.                         else
  671.                             SpacePause(" <---- Jake Dies! Push Space ");
  672.                     }
  673.                 }
  674.  
  675.                 Level(SAMELEVEL, sammy);
  676.                 PrintScore(NumPlayers, sammy[0].score, sammy[1].score, sammy[0].lives, sammy[1].lives);
  677.  
  678.                 // Play next round, until either of snake's lives have run out.
  679.             }
  680.             while (sammy[0].lives != 0 && sammy[1].lives != 0);
  681.         }
  682.  
  683.         /// <summary>Checks the global  arena array to see if the boolean flag is set</summary>
  684.         private static bool PointIsThere(int row, int col, int acolor)
  685.         {
  686.             if (row != 0)
  687.                 return (arena[row, col].acolor != acolor);
  688.             return false;
  689.         }
  690.  
  691.         /// <summary>Prints players scores and number of lives remaining</summary>
  692.         private static void PrintScore(int NumPlayers, int score1, int score2, int lives1, int lives2)
  693.         {
  694.             Console.ForegroundColor = (ConsoleColor)15;
  695.             Console.BackgroundColor = (ConsoleColor)colorTable[3];
  696.  
  697.             if (NumPlayers == 2)
  698.             {
  699.                 ConsoleSetCursorPosition(1, 1);
  700.                 Console.Write(string.Format("{0:0,0}  Lives: {1}  <--JAKE", score2, lives2));
  701.             }
  702.             ConsoleSetCursorPosition(49, 1);
  703.             Console.Write(string.Format("SAMMY-->  Lives: {0}     {1:0,0}", lives1, score1));
  704.         }
  705.  
  706.         /// <summary>Sets row and column on playing field to given color to facilitate moving of snakes around the field.</summary>
  707.         private static void Set(int row, int col, int acolor)
  708.         {
  709.             if ((row == 50 || row == 49) && col == 80)
  710.                 return;
  711.             if (row != 0)
  712.             {
  713.                 // assign color to arena
  714.                 arena[row, col].acolor = acolor;
  715.                 // Get real row of pixel
  716.                 var realRow = arena[row, col].realRow;
  717.                 // Deduce whether pixel is on top▀, or bottom▄
  718.                 bool topFlag = arena[row, col].sister == 1;
  719.                 // Get arena row of sister
  720.                 var sisterRow = row + arena[row, col].sister;
  721.                 // Determine sister's color
  722.                 var sisterColor = arena[sisterRow, col].acolor;
  723.  
  724.                 ConsoleSetCursorPosition(col, realRow);
  725.  
  726.                 // If both points are same
  727.                 if (acolor == sisterColor)
  728.                 {
  729.                     Console.ForegroundColor = (ConsoleColor)acolor;
  730.                     Console.BackgroundColor = (ConsoleColor)acolor;
  731.                     Console.Write(BlockChar);
  732.                 }
  733.                 else
  734.                 {
  735.                     if (topFlag)
  736.                     {
  737.                         Console.ForegroundColor = (ConsoleColor)acolor;
  738.                         Console.BackgroundColor = (ConsoleColor)sisterColor;
  739.                         Console.Write(BlockUpperChar);
  740.                     }
  741.                     else
  742.                     {
  743.                         Console.ForegroundColor = (ConsoleColor)acolor;
  744.                         Console.BackgroundColor = (ConsoleColor)sisterColor;
  745.                         Console.Write(BlockLowerChar);
  746.                     }
  747.                 }
  748.             }
  749.         }
  750.  
  751.         /// <summary>Pauses game play and waits for space bar to be pressed before continuing</summary>
  752.         private static void SpacePause(string text)
  753.         {
  754.             Console.ForegroundColor = (ConsoleColor)colorTable[4];
  755.             Console.BackgroundColor = (ConsoleColor)colorTable[5];
  756.             Center(11, SpacePauseUpperLine);
  757.             Center(12, new String(BlockChar, 1) + (text + new String(' ', 31)).Substring(0, 31) + new String(BlockChar, 1));
  758.             Center(13, SpacePauseLowerLine);
  759.  
  760.             while (Console.KeyAvailable)
  761.                 Console.ReadKey(true);
  762.             while (Console.ReadKey(true).Key != ConsoleKey.Spacebar) { }
  763.             Console.ForegroundColor = (ConsoleColor)15;
  764.             Console.BackgroundColor = (ConsoleColor)colorTable[3];
  765.  
  766.             // Restore the screen background
  767.             for (int i = 21; i <= 26; i++)
  768.             {
  769.                 for (int j = 24; j <= 57; j++)
  770.                 {
  771.                     Set(i, j, arena[i, j].acolor);
  772.                 }
  773.             }
  774.         }
  775.  
  776.         /// <summary>Creates flashing border for intro screen</summary>
  777.         private static void SparklePause()
  778.         {
  779.             Console.ForegroundColor = (ConsoleColor)4;
  780.             Console.BackgroundColor = (ConsoleColor)0;
  781.  
  782.             bool stop = false;
  783.             var t = new Thread(() =>
  784.             {
  785.                 string aa = "*    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    ";
  786.  
  787.                 while (!stop)
  788.                 {
  789.                     for (int a = 1; a <= 5; a++)
  790.                     {
  791.                         Thread.Sleep(50);
  792.  
  793.                         // print horizontal sparkles
  794.                         ConsoleSetCursorPosition(1, 1);
  795.                         Console.Write(aa.Substring(a, 80));
  796.                         ConsoleSetCursorPosition(1, 22);
  797.                         Console.Write(aa.Substring(6 - a, 80));
  798.  
  799.                         // Print Vertical sparkles
  800.                         for (int b = 2; b <= 21; b++)
  801.                         {
  802.                             var c = (a + b) % 5;
  803.                             if (c == 1)
  804.                             {
  805.                                 ConsoleSetCursorPosition(80, b);
  806.                                 Console.Write("*");
  807.                                 ConsoleSetCursorPosition(1, 23 - b);
  808.                                 Console.Write("*");
  809.                             }
  810.                             else
  811.                             {
  812.                                 ConsoleSetCursorPosition(80, b);
  813.                                 Console.Write(" ");
  814.                                 ConsoleSetCursorPosition(1, 23 - b);
  815.                                 Console.Write(" ");
  816.                             }
  817.                         }
  818.                     }
  819.                 }
  820.             });
  821.             t.Start();
  822.             Console.ReadKey(true);
  823.             stop = true;
  824.             t.Join();
  825.         }
  826.  
  827.         /// <summary>Determines if users want to play game again.</summary>
  828.         private static bool StillWantsToPlay()
  829.         {
  830.             Console.ForegroundColor = (ConsoleColor)colorTable[4];
  831.             Console.BackgroundColor = (ConsoleColor)colorTable[5];
  832.             Center(10, GameOverLine1);
  833.             Center(11, GameOverLine2);
  834.             Center(12, GameOverLine3);
  835.             Center(13, GameOverLine4);
  836.             Center(14, GameOverLine5);
  837.  
  838.             char kbd;
  839.             do
  840.                 kbd = char.ToUpperInvariant(Console.ReadKey(true).KeyChar);
  841.             while (kbd != 'Y' && kbd != 'N');
  842.  
  843.             Console.ForegroundColor = (ConsoleColor)15;
  844.             Console.BackgroundColor = (ConsoleColor)colorTable[3];
  845.             Center(10, "                                 ");
  846.             Center(11, "                                 ");
  847.             Center(12, "                                 ");
  848.             Center(13, "                                 ");
  849.             Center(14, "                                 ");
  850.  
  851.             if (kbd == 'N')
  852.             {
  853.                 Console.ForegroundColor = (ConsoleColor)7;
  854.                 Console.BackgroundColor = (ConsoleColor)0;
  855.                 Console.Clear();
  856.             }
  857.  
  858.             return (kbd == 'Y');
  859.         }
  860.  
  861.         private static void ConsoleSetCursorPosition(int x, int y)
  862.         {
  863.             Console.SetCursorPosition(x - 1, y - 1);
  864.         }
  865.     }
  866.  
  867.     static class ConsoleHelper
  868.     {
  869.         const int TMPF_TRUETYPE = 0x4;
  870.         const int LF_FACESIZE = 32;
  871.         const int STD_INPUT_HANDLE = -10;
  872.         const int STD_OUTPUT_HANDLE = -11;
  873.         const int STD_ERROR_HANDLE = -12;
  874.  
  875.         readonly static IntPtr InvalidHandleValue = new IntPtr(-1);
  876.  
  877.         [DllImport("Kernel32.dll", SetLastError = true)]
  878.         extern static IntPtr GetStdHandle(int handle);
  879.  
  880.         [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  881.         extern static bool GetCurrentConsoleFontEx(IntPtr hConsoleOutput, bool bMaximumWindow, [In, Out] ref CONSOLE_FONT_INFOEX lpConsoleCurrentFont);
  882.  
  883.         [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  884.         struct CONSOLE_FONT_INFOEX
  885.         {
  886.             public int cbSize;
  887.             public int Index;
  888.             public short Width;
  889.             public short Height;
  890.             public int Family;
  891.             public int Weight;
  892.             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = LF_FACESIZE)]
  893.             public string FaceName;
  894.         }
  895.  
  896.         public static IntPtr GetOutputHandle()
  897.         {
  898.             IntPtr handle = GetStdHandle(STD_OUTPUT_HANDLE);
  899.             if (handle == InvalidHandleValue)
  900.                 throw new Win32Exception();
  901.             return handle;
  902.         }
  903.  
  904.         public static bool IsOutputConsoleFontTrueType()
  905.         {
  906.             CONSOLE_FONT_INFOEX cfi = new CONSOLE_FONT_INFOEX();
  907.             cfi.cbSize = Marshal.SizeOf(typeof(CONSOLE_FONT_INFOEX));
  908.             if (GetCurrentConsoleFontEx(GetOutputHandle(), false, ref cfi))
  909.                 return (cfi.Family & TMPF_TRUETYPE) == TMPF_TRUETYPE;
  910.             return false;
  911.         }
  912.     }
  913. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement