Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

CSC112 Spring 2016 Examples

2370 views
head	1.1;
access;
symbols;
locks
	3066ab4dbfbb4db89cf9d66ff38c3e1a:1.1; strict;
comment	@// @;


1.1
date	2016.03.17.15.57.00;	author pngwen;	state Exp;
branches;
next	;


desc
@@


1.1
log
@Initial revision
@
text
@// The main file for the puzzle program.
// Play the triangle puzzle without the impending check from the Cracker Barrel server!
// Revision: $Revision$
// Change Log
//   $Log$

#include <iostream>
#include <string>
#include <unistd.h>
#include <iomanip>
#include "termmanip.h"
#include "keystream.h"
#include "trianglePuzzle.h"
#include "tty_functions.h"

using namespace std;

// One static global variable, used sparingly but in good faith as there is but one tty
static ttySize sz;

//display elements
void displayHeader();
void displayFooter();
void displayMessage(int line, const string &msg);
void displayMoveResponse(TrianglePuzzle *p, bool valid);

int main()
{
  TrianglePuzzle *p;
  keycode kc;

  //initialize things
  sz = ttyGetSize(STDIN_FILENO);
  p=new TrianglePuzzle();
  
  //display the puzzle
  cout << clearScreen << cursorOff;
  p->display();

  displayHeader();
  displayFooter();
  
  //get the input into the right state
  kin.rawMode();

  //do the puzzle
  do {
    kc = kin.getKey();

    //moves begin valid
    displayMoveResponse(p, true);
    
    switch(kc) {
    case UP:  //up
    case 'k': //with vim bindings!
    case CTRL_P: //and emacs too
    case 'w': //gamer!
      p->up();
      break;
      
    case DOWN: //down
    case 'j': //with vim bindings!
    case CTRL_N: //and emacs too!
    case 's': //gamer!
      p->down();
      break;

    case LEFT: //left
    case 'h': //with vim bindings!
    case CTRL_B: //and emacs!
    case 'a': //gamer!
      p->left();
      break;

    case RIGHT: //right
    case 'l': //vim!
    case CTRL_F: //emacs!
    case 'd': //gamer!
      p->right();
      break;

    case 'r':
      p->reset();
      break;

    case ENTER:  //make yer move!
      displayMoveResponse(p, p->move());
      break;
      
    case ESC:
      kc = CTRL_C; //escape moves too
      break;
    }
  } while(kin && kc != CTRL_C);

  //clean up the screen
  cout << cursorOn << clearScreen << cursorPosition(1,1);
  cout.flush();
  
  return 0;
}


void
displayHeader()
{
  //put a header on the screen
  cout << cursorPosition(1,1)
       << reverseVideo
       << clearLine << setw(sz.cols) << ' ';
  displayMessage(1, "Triangle Peg Puzzle");
  cout << cursorPosition(1,2) << normal;
  cout.flush();
}


void
displayFooter()
{
  displayMessage(sz.rows-1, "Arrows/jkhl/wasd - Move Cursor     Enter: Select/Place Peg");
  displayMessage(sz.rows,   "r- Reset                           ESC - Exit");
}


void
displayMessage(int line, const string &msg)
{
  //compute the x-coordinate to center the message
  int x = sz.cols/2;
  x -= msg.length()/2;
  cout << cursorPosition(x, line) << msg;
  cout.flush();
}


void
displayMoveResponse(TrianglePuzzle *p, bool valid)
{
  int y;

  //get the line to display the message on
  y=p->y() - 1;

  //clear the message line
  cout << cursorPosition(1,y) << clearLine;
  cout.flush();

  //display the message (if there is one)
  if(!valid) {
    cout << red;
    displayMessage(y, "Invalid Selection.  Please Try Again");
    cout << normal;
    cout.flush();
  }
}
@