/*
Free Battleship clone for Win32/Linux Console.
Copyright (C) 2005 Dennis Gertitschke
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 "../inc/Screen.h"
#include "../inc/Error.h"
#include "../inc/Common.h"
#include <stdlib.h>
#include <iostream>
#ifdef WIN32
#include <windows.h>
#include <conio.h>
#endif
using namespace std;
Screen::Screen(){
m_iMode=GAMETYPE_PLAYER_VS_COMPUTER;
}
Screen::~Screen(){
}
void Screen::setMode(int iMode){
m_iMode=iMode;
}
void Screen::clrscr(){
fflush(stdout);
#ifdef WIN32
system("cls");
#else
system("clear");
#endif
}
void Screen::clrlne(int iX,int iY){
gotoxy(iX,iY);
cout<<" ";
gotoxy(iX,iY);
fflush(stdout);
}
void Screen::gotoxy(int iX,int iY){
#ifdef WIN32
COORD point={(short)iX,(short)iY};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),point);
#else
cout<<"\x1b["<<iY<<";"<<iX<<"H";
fflush(stdout);
#endif
}
void Screen::drawBoard(){
int i,j,k;
clrscr();
gotoxy(1,1);
if(m_iMode==GAMETYPE_PLAYER_VS_COMPUTER)
cout<<"*** Enemy sea ***";
if(m_iMode==GAMETYPE_COMPUTER_VS_COMPUTER)
cout<<"*** A.I. Player One ***";
gotoxy(49,1);
if(m_iMode==GAMETYPE_PLAYER_VS_COMPUTER)
cout<<"*** Your sea ***";
if(m_iMode==GAMETYPE_COMPUTER_VS_COMPUTER)
cout<<"*** A.I. Player Two ***";
gotoxy(2,3);
cout<<"A B C D E F G H I J";
gotoxy(50,3);
cout<<"A B C D E F G H I J";
for(i=0;i<11;i++){
gotoxy(2,4+i);
cout<<"_____________________________";
gotoxy(50,4+i),
cout<<"_____________________________";
#ifdef WIN32
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
#else
cout<<"\x1b[44m";
#endif
}
for(j=0;j<10;j++){
for(i=1;i<32;i+=3){
gotoxy(i,5+j);
cout<<"|";
}
for(k=49;k<80;k+=3){
gotoxy(k,5+j);
cout<<"|";
}
}
#ifdef WIN32
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
#else
cout<<"\x1b[0m";
#endif
for(k=0;k<10;k++){
gotoxy(32,5+k);
cout<<(1+k);
gotoxy(47,5+k);
cout<<(1+k);
}
fflush(stdout);
}
int Screen::printMenu(){
int iChoice;
clrscr();
cout<<"******************************\n";
cout<<"* *\n";
cout<<"* BATTLESHIP *\n";
cout<<"* Version 1.2.1 *\n";
cout<<"* *\n";
cout<<"******************************\n";
cout<<"<1>Player vs. Computer\n";
cout<<"<2>Computer vs. Computer\n";
cout<<"<3>Exit\n";
cout<<" ";
fflush(stdout);
cin>>iChoice;
return iChoice;
}
void Screen::displayHit(int iX,int iY){
gotoxy(iX,iY);
#ifdef WIN32
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_BLUE|FOREGROUND_RED);
#else
cout<<"\x1b[44;31m";
#endif
#ifdef WIN32
cout<<"\xFE";
PlaySound("..\\sound\\kaboom.wav",NULL,SND_SYNC);
#else
cout<<"\xFE";
::playWave("../sound/kaboom.wav",8,1,8000);
#endif
#ifdef WIN32
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
#else
cout<<"\x1b[0m";
#endif
fflush(stdout);
}
void Screen::displayMiss(int iX,int iY){
gotoxy(iX,iY);
#ifdef WIN32
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
#else
cout<<"\x1b[44;37m";
#endif
cout<<"O";
#ifdef WIN32
PlaySound("..\\sound\\splash.wav",NULL,SND_SYNC);
#else
::playWave("../sound/splash.wav",8,1,8000);
#endif
#ifdef WIN32
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
#else
cout<<"\x1b[0m";
#endif
fflush(stdout);
}
void Screen::displayShip(int iX,int iY){
gotoxy(iX,iY);
#ifdef WIN32
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_BLUE|FOREGROUND_INTENSITY);
#else
cout<<"\x1b[44m";
#endif
cout<<"\xFE";
#ifdef WIN32
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
#else
cout<<"\x1b[0m";
#endif
fflush(stdout);
}
int Screen::printCredits(bool bYouLost,bool bComputerLost){
int iChoice;
clrscr();
if(bComputerLost&&m_iMode==GAMETYPE_PLAYER_VS_COMPUTER){
cout<<"YOU HAVE ACHIEVED A GLORIOUS VICTORY!!!\n\n";
#ifdef WIN32
PlaySound("..\\sound\\fanfare3.wav",NULL,SND_SYNC);
#else
::playWave("../sound/fanfare3.wav",8,1,8000);
#endif
}
if(bComputerLost&&m_iMode==GAMETYPE_COMPUTER_VS_COMPUTER)
cout<<"A.I. Player Two won!!!\n\n";
if(bYouLost&&m_iMode==GAMETYPE_PLAYER_VS_COMPUTER){
cout<<"YOU HAVE BEEN DEFEATED BY A MACHINE!!!\n\n";
#ifdef WIN32
PlaySound("..\\sound\\evil.wav",NULL,SND_SYNC);
#else
::playWave("../sound/evil.wav",8,1,8000);
#endif
}
if(bYouLost&&m_iMode==GAMETYPE_COMPUTER_VS_COMPUTER)
cout<<"A.I. Player One won!!!\n\n";
cout<<"Battleship v1.2.1, Copyright (C) 2005 Dennis Gertitschke\n";
cout<<"Battleship comes with ABSOLUTELY NO WARRANTY.\n";
cout<<"This is free software, and you are welcome to redistribute\n";
cout<<"it under certain conditions.\n";
if(bComputerLost||bYouLost){
cout<<"\nDo you want to play another one? [1]=Yes"
<<"\n [2]=No"
<<"\n [3]=Back to main menu"
<<"\n ";
fflush(stdout);
cin>>iChoice;
return iChoice;
}
#ifdef WIN32
else
getch();
#endif
return 0;
}
void Screen::promptUserToHide(const char* pszType,int iLength){
clrlne(2,16);
cout<<"Deploy your fleet!";
clrlne(2,17);
cout<<pszType<<" (length "<<iLength<<") enter bearing + start-/endpoint: ";
fflush(stdout);
}
void Screen::promptUserToShoot(){
clrlne(2,16);
clrlne(2,17);
clrlne(2,18);
cout<<"Select a target field!";
fflush(stdout);
}
void Screen::printUserStatus(bool bHit,const char *pszType,bool bSunk){
if(m_iMode==GAMETYPE_PLAYER_VS_COMPUTER){
clrlne(2,24);
if(bHit){
if(bSunk)
cout<<"The computer sunk your "<<pszType<<"!";
else
cout<<"The computer hit your "<<pszType<<"!";
}
else
cout<<"The computer didn't hit anything at all!";
fflush(stdout);
}
}
void Screen::printCompStatus(bool bHit,const char *pszType,bool bSunk){
if(m_iMode==GAMETYPE_PLAYER_VS_COMPUTER){
clrlne(2,23);
if(bHit){
if(bSunk)
cout<<"You sunk the computers "<<pszType<<"!";
else
cout<<"You hit the computers "<<pszType<<"!";
}
else
cout<<"You didn't hit anything at all!";
fflush(stdout);
}
}
void Screen::getDirection(char& cRefDirection){
char cTmpX;
try{
clrlne(2,18);
cout<<"(h)orizontal or (v)ertical: ";
fflush(stdout);
cin>>cTmpX;
if(cin.fail()){
Error myerror("Invalid input");
throw myerror;
}
}
catch(const Error& refError){
cin.clear();
printErrorMsg(refError);
cin.ignore(80,'\n');
getDirection(cTmpX);
}
cRefDirection=static_cast<char>(cTmpX&0xDF);
}
void Screen::getUserCoordinate(char& cRefX,int& iRefY){
char cTmpX;
int iTmpY;
try{
clrlne(2,19);
cout<<"Horizontal (A-J): ";
fflush(stdout);
cin>>cTmpX;
if(cin.fail()){
Error myerror("Invalid input");
throw myerror;
}
clrlne(2,20);
cout<<"Vertical (1-10): ";
fflush(stdout);
cin>>iTmpY;
if(cin.fail()){
Error myerror("Invalid input");
throw myerror;
}
}
catch(const Error& refError){
cin.clear();
printErrorMsg(refError);
cin.ignore(80,'\n');
getUserCoordinate(cTmpX,iTmpY);
}
cRefX=static_cast<char>(cTmpX&0xDF);
iRefY=iTmpY;
clrlne(2,19);
clrlne(2,20);
}
void Screen::printUserSucessfullyPlaced(){
if(m_iMode==GAMETYPE_PLAYER_VS_COMPUTER){
clrlne(2,23);
cout<<"Your fleet is ready for battle!";
fflush(stdout);
}
}
void Screen::printCompSucessfullyPlaced(){
if(m_iMode==GAMETYPE_PLAYER_VS_COMPUTER){
clrlne(2,24);
cout<<"The computers fleet is ready for battle!";
fflush(stdout);
}
}
void Screen::printErrorMsg(const Error& refError){
clrlne(2,23);
refError.print();
fflush(stdout);
}
void Screen::clearErrorMsg(){
clrlne(2,23);
fflush(stdout);
}