CSC112 Spring 2016 Examples
head 1.1;
access;
symbols;
locks; strict;
comment @// @;
1.1
date 2016.03.17.15.59.57; author pngwen; state Exp;
branches;
next ;
desc
@@
1.1
log
@Initial revision
@
text
@// Functions for the TrianglePuzzle Class
// Revision: $Revision$
// Change Log
// $Log$
#include <iostream>
#include <unistd.h>
#include "tty_functions.h"
#include "trianglePuzzle.h"
#include "keystream.h"
#include "termmanip.h"
using namespace std;
TrianglePuzzle::TrianglePuzzle(int _x, int _y) : Widget(_x, _y, 27, 9), pegs(5)
{
int coff = 12;
int roff = 0;
//build the puzzle
for(int row=1; row<=5; row++) {
for(int col=0; col < row; col++) {
pegs[row-1].push_back(new Peg(_x + coff + (col * 6), _y+roff));
if(row != 1) {
pegs[row-1][col]->place();
}
}
//update the offsets
roff+=2;
coff-=3;
}
//set up the cursor stuff
this->cx = this->cy = 0;
this->mx = this->my = -1;
//select the default peg
this->pegs[this->cy][this->cx]->select();
}
TrianglePuzzle::TrianglePuzzle() : TrianglePuzzle(1, 1)
{
//put ourselves in the middle of the screen
ttySize size = ttyGetSize(STDIN_FILENO);
//compute the midpoint
int mx = size.cols / 2 - 13;
int my = size.rows / 2 - 4;
//set ourselves to the midpoint and then adjust for the offset
x(mx);
y(my);
for(auto ritr=pegs.begin(); ritr!=pegs.end(); ritr++) {
for(auto citr=ritr->begin(); citr != ritr->end(); citr++) {
(*citr)->x((*citr)->x() + mx);
(*citr)->y((*citr)->y() + my);
}
}
}
TrianglePuzzle::~TrianglePuzzle()
{
//delete all the pegs!
for(auto ritr=pegs.begin(); ritr!=pegs.end(); ritr++) {
for(auto citr=ritr->begin(); citr != ritr->end(); citr++) {
delete *citr;
}
}
}
void
TrianglePuzzle::display()
{
//display all the pegs
for(auto ritr=pegs.begin(); ritr!=pegs.end(); ritr++) {
for(auto citr=ritr->begin(); citr != ritr->end(); citr++) {
(*citr)->display();
}
}
}
//select a given peg
void
TrianglePuzzle::selectPeg(int px, int py)
{
//unselect the current one
pegs[cy][cx]->deselect();
//correct potential issues in y first
if(py < 0) {
//torus up!
py = pegs.size() - 1;
} else if (py >= pegs.size()) {
//torus down!
py = 0;
}
//correct x
if(px < 0) {
//torus left!
px = pegs[py].size() -1;
} else if(px >= pegs[py].size()) {
//torus right!
px = 0;
}
//select the chosen one and redisplay
this->cx = px;
this->cy = py;
pegs[cy][cx]->select();
display();
}
//move the selection up a row
void
TrianglePuzzle::up()
{
//kick it up a notch
selectPeg(cx, cy-1);
}
//move the selection down a row
void
TrianglePuzzle::down()
{
//bring it on down
selectPeg(cx, cy+1);
}
//move the selection right a column
void
TrianglePuzzle::right()
{
//to the right, the right....
selectPeg(cx+1, cy);
}
//move the selection left a column
void
TrianglePuzzle::left()
{
//to the left, the left...
selectPeg(cx-1, cy);
}
//perform a part of a move. Returns true if valid, false if invalid
bool
TrianglePuzzle::move()
{
int dx, dy;
int midx, midy;
int sx, sy;
//handle the first selection
if(mx == -1) {
//can't select holes, only pegs
if(!pegs[cy][cx]->isOccupied()) return false;
//select the peg!
mx = cx;
my = cy;
pegs[my][mx]->color(red);
pegs[my][mx]->display();
return true;
}
//ok, so it's the second selection! First, let's turn off the highlighting
pegs[my][mx]->color(normal);
pegs[my][mx]->display();
//get the starting point
sx = mx;
sy = my;
//reset move state
my=mx=-1;
//'now, let's check to see if the user is playing fair
if(pegs[cy][cx]->isOccupied()) return false; //this means that it's not a blank square
//midpoints and distances
midx = (cx+sx)/2;
midy = (cy+sy)/2;
dx = cx - sx;
dy = cy - sy;
if(dx<0) dx *= -1;
if(dy<0) dy *= -1;
//validate same row moves
if(dy == 0 && dx != 2) return false;
//validate different row moves
if(dy != 0 && dy != 2) return false;
if(dx != 2 && dx != 0) return false;
//validate that we are skipping a peg
if(!pegs[midy][midx]->isOccupied()) return false;
//HUZZAH! make the move!
pegs[sy][sx]->take();
pegs[cy][cx]->place();
pegs[midy][midx]->take();
return true;
}
void
TrianglePuzzle::reset()
{
for(int y=0; y<pegs.size(); y++) {
for(int x=0; x<pegs[y].size(); x++) {
//the first row is empty, all others are taken
if(y==0) {
pegs[y][x]->take();
} else {
pegs[y][x]->place();
}
}
}
}
@