Gomoku winning condition c++ using pointers and arrays - c++

I am currently working on a Gomoku game in c++. But I'm stuck with the winning conditions. I'm new to c++. I need to add the winning conditions using pointers for this game. Please I need help. I don't know how to start with it. So far I can only insert the player moves into the arrays. I need the pointers to determine the 8 directions for the winning condition.
Winning conditions are:
5 in a row horizontally, vertically, diagonally (but this must also be changed to 3 in a row, 4 in a row etc)
the header file
// file goboard.h
class boardBox{
public:
char PlayerColor; //z or W // 7 0 1
boardBox* neighbours[8]; // 6 2
boardBox( ); // 5 4 3
};//boardBox
class goboard {
private:
boardBox* entrance;
int height, width;
static const int gridX = 6;
static const int gridY = 7;
char grid[gridX][gridY];
// TODO
public:
void ask_turn(char symb);
goboard ( );
goboard (int height, int width);
~goboard ( );
void showBoard( );
void generate();
// TODO
};//goboard
this file linked with the header file
// file goboard.cc
#include <iostream>
#include "goboard.h"
using namespace std;
goboard::goboard ( ) {
// TODO
}//goboard::goboard
goboard::~goboard ( ) {
// TODO
}//goboard::~goboard
void goboard::generate()
{
cout << "Board shows like this." << endl;
int number = 1;
for(int x = 0; x < gridX; x++)
{
for(int y = 0; y < gridY; y++)
{
grid[x][y] = '.';
}
}
}
void goboard::showBoard( ) {
printf("\n................\n");
for(int x = 0; x < gridX; x++)
{
for(int y = 0; y < gridY; y++)
{
printf("%c |", grid[x][y]);
}
printf("\n");
}
cout<<endl;
// TODO
}//goboard::showBoard
void goboard::ask_turn(char symb) //symb is symbol Z or W
{
int input;
int input2;
while( true )
{
cout<<"Where would you like to play?"<<endl;
cin>>input;
cin>>input2;
int index = input;
int index2 = input2;
int row = index;
int col = index2;
char grid_position = grid[row][col];
if(grid_position == 'Z' || grid_position == 'W')
{
puts("That grid position is already take!");
}else{
grid[row][col] = symb;
break;
}
}
}
// TODO
The main file
// file hoofd.cc
#include <iostream>
#include <string>
#include "gobord.h"
#define GRID_SIZE 3
using namespace std;
int main (int argc, char *argv[] ) {
goboard Goboard;
Goboard.generate();
char symb = 'Z';
char symb1 = 'W';
while(true){
Goboard.showBoard( );
Goboard.ask_turn(symb);
Goboard.showBoard();
Goboard.ask_turn(symb1);
}
return 0;
}//main

EDIT: You need to change your datastructure from a char[][] to a boardBox[][].
In your constructor, you need to fix up each boardBox' neighbours array as follows:
goboard::goboard() {
for (int r = 0; r < gridX; r++) {
for (int c = 0; c < gridY; c++) {
boardBox& box = grid[r][c];
box.neighbours[0] = get_box(r-1, c);
box.neighbours[1] = get_box(r-1, c+1);
// and so on
}
}
}
boardBox* goboard::get_grid(int row, int col) {
return in_board(row, col) ? &grid[row][col] : nullptr;
}
where get_grid returns a pointer to the boardBox or a null pointer if that cell is out of bounds.
A win condition happens right after a move, so logically the just-placed piece must be part of the five-in-a-row in either direction.
Let's first implement a function that follows a certain direction and counts the number of pieces of a given symbol in that direction:
int count_direction(boardBox *box, int direction, char symb) {
int count = 0;
while (box) {
if (box->playerColor != symb)
break;
box = box->neighbours[direction];
}
return count;
}
This follows the pointers in the neighbours array until we hit the end of the board, denoted by a null pointer.
We can use this as follows to count the number of pieces along a diagonal:
boardBox *box = get_grid(row, col);
int count_diagonal1 = count_direction(box, 3, symb) // down and to the right
+ count_direction(box, 7, symb) // up and to the left
- 1; // count_direction visits (row,col) twice!
Implementing the other directions and determining the win condition from the counts is left to you :)

Related

How to move "an animated character" with rading "moves" from the text file into array in c++?

I am creating a map and have an animated character move through the map.
I need to read 30 moves from a text file into a 1D array named moves[]. Each move is one of these letters: UDLR(for up, down, left, right respectively)
I tried the build the program and I created a map and successfully display "animated character" in the map, but can not move it around.
I think the problem is occuring when I am reading file.
This is the code that I wrote.
include "game.h"
#include "surface.h"
#include <cstdio> //printf
#include <fstream>
#include <string>
using namespace std;
namespace Tmpl8{
// -----------------------------------------------------------
string moves[30];
int bmap[10][16] =
{
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,1,0,0,0,0,1,0,1,1,0,1},
{1,0,0,0,0,0,1,0,0,1,0,1,0,1,0,1},
{1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1},
{1,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1},
{1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1},
{1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
{1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,1}
};
Sprite theBackgroundSprite(new Surface("assets/map.tga"), 2);
Sprite theMarioSprite(new Surface("assets/char.tga"), 4);
int X = 1;
int Y = 1;
long int frameNumber = 0;
void Game::Init()
{
string myNum;
//Read "moves" from the text file into array
ifstream MyReadFile("Text.txt");
int i = 0;
while (getline(MyReadFile, myNum))
{
moves[i] = myNum;
}
MyReadFile.close();
//Draw background map
for (int j = 0; j < 10; j++)
{
for (int i = 0; i < 16; i++)
{
theBackgroundSprite.SetFrame(bmap[j][i]);
theBackgroundSprite.Draw(screen, i * 50, j * 50);
}
}
}
void Game::Shutdown()
{
}
static int frame = 0;
static int moveNumber = 0;
// -----------------------------------------------------------
void Game::Tick(float deltaTime)
{
frameNumber++;
if ((frameNumber % 10) == 0)
{
if (moveNumber < 30)
{
moveNumber++;
//Draw background map...
for (int j = 0; j < 10; j++)
{
for (int i = 0; i < 16; i++)
{
theBackgroundSprite.SetFrame(bmap[j][i]);
theBackgroundSprite.Draw(screen, i * 50, j * 50);
}
}
if (moves[moveNumber] == "R") X++;
if (moves[moveNumber] == "L") X--;
if (moves[moveNumber] == "U") Y--;
if (moves[moveNumber] == "D") Y++;
theMarioSprite.SetFrame(moveNumber % 4);
theMarioSprite.Draw(screen, X * 50, Y * 50);
//update X and Y coordinates depending on the value (LRUD) from the
moves[] array
//set the correct frame (1-4) from the Mario sprite
//redraw the sprite
}
}
}
};
console window
text file img

Instantiating and placing characters or strings onto a board for game

I have to create a Battleship game where the first part asks to create a Ship class and initialize five instance of the ship class:
Frigate(len 2),
Sub (len 3),
Destroyer (len 3),
Battleship (len 4),
Aircraft Carrier (len 5)
Ships have to take random spots on the board and show each ship position using the first letter of the ship name.
No hit or miss functions yet.
I feel like I have no idea how to approach this.
So far, I've created the board successful. I feel like I might have to make an area for the placements of ships on the board.
I'm so sorry. My code looks like garbage and I really need some guidance :(
Edit: I've made a ship placement function and fixed my class, but not sure if they're correct
#include <iostream>
#include <ctime>
using namespace std;
const int ROWS = 10;
const int COLS = 10;
const int SHIPTYPE = 5;
string array[ROWS][COLS];
// Create struct with horizontal and vertical coordinates
struct Arr{
int x;
int y;
};
class Ship(){
// Declare ship type
string type;
// Declare length of int type for points on grid
int length;
// Coordinates of grid with max length of ship (0-4)
Arr board[5];
Ship[SHIPTYPE];
enum direct h, v;
struct Placeship{
direct dir;
Ship shipType;
};
};
void Board()
{
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
array[i][j] = '-';
}
}
}
void VBoard()
{
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
cout << array[i][j] << " ";
}
cout << endl;
}
}
// Make a function that allows for ship placement
Placeship(){
int x, y, z;
Placeship sp;
// Bad return
sp.shipType.board[0].X = -1;
// User input for integers
cin >> x >> y >> z;
if(x!=0 && x! = 1){
return sp;
}
else if (y < 0 || y >= ROWS){
return sp;
}
else (y > 0 || y >= COLS){
return sp;
}
// Include direction: Horizontal and Vertical
sp.direction = (direct)x;
sp.shipType.board[0].X = y;
sp.shipType.board[0].Y = z;
return sp;
}
// Create function to set or load ships
void setShip(){
// Include data for ships
ship_t[0].type = "Frigate"; ship_t[0].length = 2;
ship_t[1].type = "Sub"; ship_t[1].length = 3;
ship_t[2].type = "Destroyer"; ship_t[2].length = 3;
ship_t[3].type = "Battleship"; ship_t[3].length = 4;
ship_t[4].type = "Aircraft Carrier"; ship_t[4].length = 5;
}
int main()
{
//Call functions
Board();
VBoard();
Placeship();
setShip();
return 0;
}
Is this a homework? It is asking you to define a class for the Ship object with two (so far) properties: a type/name (can be reduced to a single character), and a length. Here is one way of doing this:
class Ship
{
public:
Ship(char n) : n_(n)
{
switch(n_)
{
case 'F': len_ = 2; break;
case 'S': len_ = 3; break;
case 'D': len_ = 3; break;
case 'B': len_ = 4; break;
case 'A': len_ = 5; break;
default: // process bad input
}
}
private:
char n_;
int len_;
}
However, being familiar with the game, I know that ships don't play any role in it: the board is responsible for hit / miss response, and everything else. So I don't think you need that Ship class at all!
Please ask another question

Segmentation Fault when dealing with 2D Arrays [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm am trying to dynamically make 2d arrays that are then supposed to be iterated through to check their contents. Whenever I try to use a function that indexes the array I get a segmentation fault. The two functions that are creating the problems are the printg() and get() functions. I'm not sure exactly what I'm doing wrong, but neither of them will work properly for me.
Any help would be great. Thank you.
#ifndef _GRID_H
#define _GRID_H
#include <iostream>
using namespace std;
class Grid
{
public:
Grid();
Grid(const Grid& g2);
Grid(int x, int y, double density);
Grid(string file);
~Grid();
bool check(int x, int y); //check if a cell is inhabited or not
bool isEmpty();//check if a grid is living
bool equals(const Grid& g2);//checks if two grids are equal
void kill(int x, int y);//kill a cell
void grow(int x, int y);//grow a cell
int getSize();
int getNumRows();
int getNumCol();
int getNumLiving();
void printg(int r, int c);
char get(int x, int y) const;
private:
int size; //number of cells in grid
int row; //row length (number of columns)
int column; //column length (number of rows)
int num_living; //number of X's in the grid
char** myGrid;
};
#endif
#include "Grid.h"
#ifndef _GRID_C
#define _GRID_C
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
//compile with g++ -I /home/cpsc350/GameOfLife Grid.cpp
using namespace std;
Grid::Grid() //do i need a default constructor????
{
char myGrid[10][10] = {{0,1,2,3}, {4,5,6,7}, {8,9,10,11}};
row = 10;
column = 10;
size = 100;
}
Grid::Grid(const Grid& g2)//copy constructor/////////////help
{
size = g2.size;
row = g2.row;
column = g2.column;
num_living = g2.num_living;
char** myGrid = new char*[row];
for(int i = 0; i < row; i++)
myGrid[i] = new char[column];
for(int i1 = 0; i1 < row; i1++)
{
for(int i2 = 0; i2 < column; i2++)
{
//copy(&g2[i1][i2], &g2[i1][i2]+row*column,&myGrid[i1][i2]);
myGrid[i1][i2] = g2.get(i1,i2);
}
}
}
Grid::Grid(int x, int y, double density)
{
char** myGrid = new char*[x];
for(int i = 0; i < x; i++)
myGrid[i] = new char[y];
row = x;
column = y;
size = x*y;
num_living = size * density;
string str = "";
for(int a = 0; a < num_living; a++)//adds the density of X's to a string
{
str += 'X';
}
for(int a = 0; a < size - num_living; a++)//adds the rest to the string
{
str += '-';
}
int randnum;
//randomly generates indicies in the string str and puts them into the array
for(int i1 = 0; i1 < column; i1++)
{
for(int i2 = 0; i2 < row; i2++)
{
//generate random numbers from index 0 to length of string - 1
if(str.length()>1)
{
randnum = (rand()%(str.length()-1))+1;
}
else
{
randnum = 0;
}
myGrid[i1][i2] = str[randnum];
str.erase(randnum);
}
}
}
Grid::Grid(string file)
{
num_living = 0;
//code to create a 2d array from a filepath
ifstream openfile(file);
//error handling
if(! openfile)
{
cout << "Error, file could not be opened" << endl;
exit(0);
}
openfile >> column;//gets number of rows
openfile >> row;//gets number of columns
size = row*column;
char** myGrid = new char*[row];
for(int i = 0; i < row; i++)
myGrid[i] = new char[column];
for(int x = 0; x<column; x++)
{
for(int y = 0; y<row; y++)
{
openfile >> myGrid[x][y];
if(! openfile)//error handling
{
cout << "Error reading file at " << row << "," << column << endl;
}
if(myGrid[x][y] == 'X')
{
num_living++;
}
}
}
openfile.close();
}
Grid::~Grid()
{
if(myGrid)
{
for(int i = 0; i < row; i++)
{
delete []myGrid[i];
}
delete []myGrid;
}
}
void Grid::kill(int x, int y)
{
if(myGrid[x][y] == 'X')
{
num_living--;
}
myGrid[x][y] = '-';
}
void Grid::grow(int x, int y)
{
if(myGrid[x][y] == '-')
{
num_living++;
}
myGrid[x][y] = 'X';
}
bool Grid::check(int x, int y)
{
if(y<0 || x<0)
{
return(false);
}
return (myGrid[x][y] == 'X');
}
bool Grid::isEmpty()
{
return (num_living == 0);
}
bool Grid::equals(const Grid& g2)
{
if(size != g2.size) //checks if sizes are equal
{
return false;
}
if(row != g2.row)//checks if numRows are equal
{
return false;
}
if(column != g2.column)//checks if numCol are equal
{
return false;
}
if(num_living != g2.num_living)//checks if numliving are equal
{
return false;
}
for(int x = 0; x < row; x++)//checks each element
{
for(int y = 0; y < column; y++)
{
if(myGrid[x][y] != g2.get(x,y))
{
return false;
}
}
}
return true;
}
int Grid::getSize()
{
return(size);
}
int Grid::getNumRows()
{
return(column);
}
int Grid::getNumCol()
{
return(row);
}
int Grid::getNumLiving()
{
return(num_living);
}
void Grid::printg(int r, int c)
{
for(int x = 0; x < r; x++)
{
for(int y = 0; y < c; y++)
{
cout << myGrid[x][y];
}
cout << endl;
}
}
char Grid::get(int x, int y) const
{
return myGrid[x][y];
}
#endif
The problem that I see at first is that both your default and copy constructor do not initialize myGrid. what you are doing in them will create an additional array with the same name which 'shadows' myGrid. instead you have to do:
Grid::Grid(const Grid& g2)
{
size = g2.size;
row = g2.row;
column = g2.column;
num_living = g2.num_living;
myGrid = new char*[row]; // removed "char**" at the start of this line
for(int i = 0; i < row; i++)
myGrid[i] = new char[column];
for(int i1 = 0; i1 < row; i1++)
{
for(int i2 = 0; i2 < column; i2++)
{
//copy(&g2[i1][i2], &g2[i1][i2]+row*column,&myGrid[i1][i2]);
myGrid[i1][i2] = g2.get(i1,i2);
}
}
}
your default constructor has the same problem. but note that you can't initialize it with braces. but you don't have to have a default constructor if you are not using it.

C++ creating a forest

am new to c++ and am trying to create a burning forest simulator. I have been trying to call a function from the forest class but i dont know how to give it an argument, if anyone could help that would be great here is the code that i have at the moment.
using namespace std;
class ForestSetup
{
private:
const char Tree = '^';
const char Fire = '*';
const char emptySpace = '.';
const char forestBorder = '#';
const int fireX = 10;
const int fireY = 10;
char forest[21][21];
public:
void CreateForest()
{
// this function is to create the forest
for (int i = 0; i < 21; i++) // this sets the value of the rows from 0 to 20
{
for (int j = 0; j < 21; j++) // this sets the value of the columns from 0 to 20
{
if (i == 0 || i == 20)
{
forest[i][j] = forestBorder; // this creates the north and south of the forest border
}
else if (j == 0 || j == 20)
{
forest[i][j] = forestBorder; // this creates the east and the west forest border
}
else
{
forest[i][j] = Tree; // this filles the rest of the arrays with trees
}
}
}
forest[fireX][fireY] = Fire; // this sets the fire in the middle of the grid
}
void ShowForest(char grid[21][21])
{
for (int i = 0; i < 21; i++)
{
for (int j = 0; j < 21; j++)
{
cout << grid[i][j];
}
cout << endl;
}
}
};
int main(void)
{
ForestSetup myForest;
myForest.ShowForest();
system("Pause");
return 0;
}
Let's say you have a setOnFire function with the x and y co-ordinates of where you want to start the fire.
public:
setOnFire(int x, int y)
{
// Code to flag that part of the forest on fire
}
In your main, you would call it with
myForest.setOnFire(5,5);
Within the ForestSetup class you just need setOnFire(5,5);
This tutorials point article might help.

Adding a random member from an array of chars to a game board in C++

I am programming a game for a university project and i am having a little trouble with it. So here is my game board class header file:
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <time.h>
class CMagicAlchemistBoard
{
public:
CMagicAlchemistBoard(void); // Default Constructor
CMagicAlchemistBoard(const CMagicAlchemistBoard& board); // Copy Constructor
~CMagicAlchemistBoard(void ); // Destructor
void SetupBoard(void); // Function to setup the board
int GetBoardSpace(int row, int col); // Get the color at row,col
// Accessor functions to get/set board size information
int GetColumns(void) const { return m_nColumns; }
void SetColumns(int nColumns) { m_nColumns = (nColumns >= 6) ? nColumns : 6; }
int GetRows(void) const { return m_nRows; }
void SetRows(int nRows) { m_nRows = (nRows >= 8) ? nRows : 8; }
void DeleteBoard(void); // Function to delete the board and free memory
void ExecuteMove(int row, int col);
bool IsGameOver(void) const; // Is the game over?
void DrawBoard(void);
bool ValidMove(int row, int col); // Function to see if a move is valid
char RandomPiece();
private:
void CreateBoard(void); //Function to create the board and allocate memory
// Class Data
int** m_arrBoard; // 2D array pointer
// Board size information
char m_arrChars[20];
int m_nColumns;
int m_nRows;
};
And here are the important parts of the game board .cpp file:
#include "cmagicalchemistboard.h"
using namespace std;
CMagicAlchemistBoard::CMagicAlchemistBoard(void)
: m_arrBoard(NULL), m_nColumns(6), m_nRows(8)
{
m_arrChars[0] = ' ';
}
CMagicAlchemistBoard::CMagicAlchemistBoard(const CMagicAlchemistBoard& board)
{
// Copy all of the regular data members
m_nColumns = board.m_nColumns; m_nRows = board.m_nRows;
m_arrBoard = NULL;
CreateBoard(); // Create a new game board of the same size
// Copy the contents of the game board
for(int row = 0; row < m_nRows; row++)
for(int col = 0; col < m_nColumns; col++)
m_arrBoard[row][col] = board.m_arrBoard[row][col];
int CMagicAlchemistBoard::GetBoardSpace(int row, int col)
{
if(row<0 || row>=m_nRows || col<0 || col>=m_nColumns) return 0;
return m_arrBoard[row][col];
}
void CMagicAlchemistBoard::CreateBoard(void)
{
// If there is already a board, delete it
if(m_arrBoard != NULL) DeleteBoard();
// Create the array of rows
m_arrBoard = new int*[m_nRows];
// Create each row
for(int row = 0; row < m_nRows; row++){
m_arrBoard[row] = new int[m_nColumns];
// Set each square to be empty
for(int col = 0; col < m_nColumns; col++)
m_arrBoard[row][col] = 0;
}
}
void CMagicAlchemistBoard::DrawBoard(void)
{
cout << "MAGIC ALCHEMIST" << endl;
cout << " ";
for(int col = 0; col < m_nColumns; col++){ printf(" ---",col); }
cout << endl;
for(int row = 0; row < m_nRows; row++)
{
for(int col = 0; col < m_nColumns; col++)
{
// printf("| %c", m_arrChars[0]);
cout << "| " << m_arrChars[0];
}
cout << "| " << endl;
}
}
So my idea is to have a function that will add one random char between 12 chars to m_arrBoard[0][2] position. Can someone help me with this please?
Create a function that returns a random character out of 12 predefined
characmters. Call it to assign a random character to m_arrBoard[0][2].
// The function to get a random character.
char getRandomChar()
{
char arr[12] = {}; // Initialize the array of characters.
int index = rand()%12;
return arr[index];
}
Somewhere down in some function....
// Assign a random character to m_arrBoard[0][2].
m_arrBoard[0][2] = getRandomChar();
Let's say you want to receive random characters from A to Z. You can try the following code:
std::vector<char> arr;
int n = (90-65 +1);//'Z'-'A'
int movePosition = 65;
for (unsigned int i = 0; i < 12; ++i)
{
int number = rand() % n;//Get a number from 0 to n-1 (where n is 26)
std::cout << "number = " << number << "; movePosition = " << movePosition << std::endl;
// To get a letter add movePosition to it so you are back in the range of 65 to 90
arr.push_back((char)(number + movePosition));
}
To see what characters you have added, you can try the following:
for (int i = 0;i<arr.size();i++)
{
std::cout << "Char=" << arr[i] << std::endl;
}