//****************************************************************// // // // Copyright (c) 1997. // // Dr. Michael A. Redmond // // // // This software may not be distributed further without permission from // // Dr Michael A. Redmond. // // // // This software is distributed WITHOUT ANY WARRANTY. No claims are made // // as to its functionality or purpose. // // // // Title: Tw_Peg.cpp // Description: Provides abstraction for twixt pegs - makes use of // point and color // Author: Dr Michael A. Redmond // // Date: 3/05/97 // // // // Overcommented because also explaining the language as well // as the program // //**************************************************************************// #include #include "point.h" #include "tw-color.h" #include "tw-peg.h" // default constructor Tw_Peg::Tw_Peg() : position(badrow,badcol), colorv(illegal) { } Tw_Peg::Tw_Peg(Point pos, Tw_Color col) : position(pos), colorv(col) { } Tw_Peg::Tw_Peg(int row, int column, Tw_Color col) : position(row,column), colorv(col) { } bool Tw_Peg::PositionFree() const { if (GetPegColor().GetColor() != empty) { return false; } else return true; } Tw_Color Tw_Peg::WhatColor() const { return GetPegColor(); } void Tw_Peg::AllOffsets(Point neighbors[]) const { Point base = GetPosition(); neighbors[0] = base.Adjust(2,1); neighbors[1] = base.Adjust(2,-1); neighbors[2] = base.Adjust(-2,1); neighbors[3] = base.Adjust(-2,-1); neighbors[4] = base.Adjust(1,2); neighbors[5] = base.Adjust(1,-2); neighbors[6] = base.Adjust(-1,2); neighbors[7] = base.Adjust(-1,-2); } // tells if two pegs are a legal distance apart for a twixt link // put here rather than with link because I want to make it // impossible to create a link with an invalid offset // So you say, put it in the constructor for link - well there // are 5 constructors for link - I want each to be able to // call a common method to check legality - it can't go in // link, because the link being checked isnt created yet // Didn't put it in Point, because that is intended to be // non-twixt specific bool Tw_Peg::LegalLinkOffset(const Tw_Peg peg2) const { Point coord1 = GetPosition(); Point coord2 = peg2.GetPosition(); clog << "Debug LegalLinkOffset - CityBlockDist = " << coord1.CityBlockDist(coord2) << " HorizDist = " << coord1.HorizDist(coord2) << " VertDist = " << coord1.VertDist(coord2) << endl; // can only be legal if the city block distance is 3 // and neither horixontal or vertical distance is 0 if (coord1.CityBlockDist(coord2) == 3) { if ((coord1.HorizDist(coord2) != 0) && (coord1.VertDist(coord2) != 0)) { return true; } // end inner if else { return false; } } // end outer if else { return false; } } bool Tw_Peg::AcceptPeg(Tw_Color col) { bool free = PositionFree(); // is color known to be legal ? // is position known to be legal for the color // gotta think that that has to be the board class's call if (free) { SetPegColor(col); return true; } else { return false; } } // determines if two pegs are equal // requires that == operator defined for Tw_Color and Point bool Tw_Peg::PegEqual(const Tw_Peg peg2) const { const Point pos1 = GetPosition(); const Tw_Color col1 = GetPegColor(); const Point pos2 = peg2.GetPosition(); const Tw_Color col2 = peg2.GetPegColor(); if ((pos1 == pos2) && (col1 == col2)) // if (col1 == col2) return true; else return false; } // inserting a Tw_Peg // uses iostream operator << - insertion into a stream // should receive as an argument an iostream object // commonly cout - standard output void Tw_Peg::Insert(ostream &sout) const { sout << GetPosition() << ": " << GetPegColor(); return; } // extracting a Tw_Peg // uses iostream operator >> - extract from a stream into object(s) // should receive as an argument an iostream object // commonly cin - standard input void Tw_Peg::Extract(istream &sin) { char colon; char space; Point position; Tw_Color color; // obtain point and color from user - pulling apart into // its components // uses the fact that >> has been defined for points and colors //sin >> position >> colon >> space >> color; sin >> position >> colon >> color; // clog << "DEBUG: " << "position: " << position << "colon: " // << colon << "space: " << space << "color: " << color << endl; // << colon << "color: " << color << endl; // use mutator functions to update the data members // (the safe way - doesn't depend on implementation) SetPosition(position); SetPegColor(color); return; } Point Tw_Peg::GetPosition() const { return position; } Tw_Color Tw_Peg::GetPegColor() const { return colorv; } void Tw_Peg::SetPosition(Point pos) { // probably need to define = publicly for Point for this to work position = pos; } void Tw_Peg::SetPegColor(Tw_Color col) { colorv = col; } // inserting a Tw_Peg // overloading built-in << so can use same syntax as with built-in object types ostream& operator<<(ostream &sout, const Tw_Peg &peg) { // uses member function for the class to actually carry out // the operation peg.Insert(sout); // return the result so that this insertion can be cascaded // with other insertions in a single expression return sout; } // extracting a Tw_Peg // overloading built-in >> so can use same syntax as with built-in object types istream& operator>>(istream &sin, Tw_Peg &peg) { // uses member function for the class to actually carry out // the operation peg.Extract(sin); // return the stream object so that this extraction can be cascaded // with other extractions in a single expression return sin; } bool operator==(const Tw_Peg &left, const Tw_Peg &right) { return left.PegEqual(right); }