Connect Four C++ - c++

I am coding the game connect four for my computer science class, everything was going great then I dont know what happened but I kept getting Sementation faults whenever I tried to run it. Here is my code.
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cctype>
using namespace std;
struct game{
char **board;
char p1;
char p2;
};
void print_board(game p, int r, int c);
bool play(game p, bool gamewon, int r, int c, int pieces);
bool check(int a, int b, game p, int r, int c, int pieces);
int drop(int b, char player, game p, int c);
int main(int argc, char *argv[]){
game p;
int r, c, pieces;
bool gamewon = false;
/*if(argc == 7) {
for(int i = 1; i < argc; i += 2) {
if(argv[i][0]=='-' && argv[i][1]=='r')
r = atoi(argv[i+1]);
else if(!strcmp(argv[i],"-c"))
c = atoi(argv[i+1]);
else if(!strcmp(argv[i],"-p")){
pieces = atoi(argv[i+1]);
while (pieces < 1){
cout << "You cannot have 0 pieces to connect." << endl;
cout << "Please enter a positive, non-zero integer"
<< " for the number of pieces to connect: ";
cin >> pieces;
}
}
else
cout << "Error." << endl;
}
}*/
r = 6;
c = 7;
pieces = 4;
p.board = new char*[r];
for(int i=0; i < r;i++)
p.board[i] = new char[c];
for(int a =0; a < r; a++){
for(int b = 0; b < c; b++)
p.board[a][b] = ' ';
}
print_board(p, r, c);
gamewon = play(p, gamewon, r, c, pieces);
return 0;
}
bool play(game p, bool gamewon, int r, int c, int pieces){
int col, hold = 0, charsPlaced = 0;
char player = 'y';
while(!gamewon){
if(hold != -1){
if(player =='y'){
cout<<"Player 1, what column do you want to put your piece? ";
player = 'r';
}
else{
cout<<"Player 2, what column do you want to put your piece? ";
player = 'y';
}
}
while(true){
if(charsPlaced == r*c) break;
cin>>col;
col--;
if(col <=r && col>= 0) break;
else cout<< "\nPlease enter a value between 1 and " << c << ": ";
if (cin.fail()){
cin.clear();
char d;
cin>>d;
}
}
if(charsPlaced == r*c) break;
hold = drop(col,player, p, c);
if(hold == -1) cout<<"Column is full!\nPlease enter another number between 1 and " << c << ": ";
else{
gamewon = check(hold, col, p, r, c, pieces);
charsPlaced ++;
print_board(p, r, c);
}
}
if(charsPlaced == r*c){
cout<<"No winner! Game is a draw\n";
return true;
}
if(player == 'y')
cout<<"Player 2 is the winner!\n";
else cout<<"Player 1 is the winner!\n";
return true;
}
void print_board(game p, int r, int c){
cout << endl;
for(int a = 0; a < r; a++){
for(int b = 0; b < c; b++)
cout << "|" << p.board[a][b];
cout << "|";
cout << endl;
for(int i = 0; i < c; i++)
cout << "--";
cout << endl;
}
}
bool check(int a, int b, game p, int r, int c, int pieces){
int vertical = 1, horizontal = 1, diagonalone = 1, diagonaltwo = 1, i , j;
cout << i << " " << b << " " << a << endl;
char player = p.board[a][b];
cout << player << endl;
for(i = a + 1; p.board[i][b] == player && i < r; i++, vertical++);
for(i = a - 1; p.board[i][b] == player && i >= 0; i--, vertical++);
if(vertical >= pieces)
return true;
for(j = b - 1; p.board[a][j] == player && j >= 0; j--, horizontal++);
for(j = b + 1; p.board[a][j] == player && j < c; j++, horizontal++);
if(horizontal >= pieces)
return true;
for(i = a - 1, j = b - 1; p.board[i][j] == player && i >= 0 && j >= 0; diagonalone++, i--, j--);
for(i = a + 1, j = b + 1; p.board[i][j] == player && i <= r && j <= c;diagonalone++, i++, j++);
if(diagonalone >= pieces)
return true;
for(i = a - 1, j = b + 1; p.board[i][j] == player && i >= 0 && j <= c; diagonaltwo++, i--, j++);
for(i = a + 1, j = b - 1; p.board[i][j] == player && i <= r && j >= 0; diagonaltwo++, i++, j--);
if(diagonaltwo >= pieces)
return true;
return false;
}
int drop(int b, char player, game p, int c){
if(b >= 0 && b <= c){
if(p.board[0][b] == ' '){
int i;
for(i = 0; p.board[i][b] == ' '; i++)
if(i == 5){
p.board[i][b] = player;
return i;
}
i--;
p.board[i][b] = player;
return i;
}
else{
return -1;
}
}
else{
return -1;
}
}

You are using
char **board;
in your game struct.
But this 2D array is never allocated and yet, you are working with it.
You are missing something like this:
in C:
board = malloc(10 * sizeof(char *));
for (int i = 0; i < 10; i++)
{
board[i] = malloc(10 * sizeof(char));
}
in C++:
board = new char*[10]
for (int i = 0; i < 10; i++)
{
board[i] = new char[10];
}

For starters, if you are in a Linux environment, valgrind is very helpful in finding where your segmentation fault is. To use it, if your program is called hello, just run it as valgrind hello.
Another method to debug these is to put cout or printf statements throughout your code, and observe what the last output was. You are probably indexing beyond the end of an array. Keep in mind that if you declare int x[5], the valid index values are 0 to 4.
You will probably need to change your for loops to < vs. <= so you aren't reading past the last part of the board (keep in mind that arrays are 0 indexed in c++).

Related

How do I make a function to check for the winning move in tic-tac-toe if the user chooses the size of the game board?

I have changed a Tic-Tac-Toe program from using a normal 3x3 grid to a grid-size chosen by the user (between 3 and 9). I am using a global constant 'SIZE' to hold the value the user chooses. My issue is adapting my winMove(); function so that it adjusts to check for the winning move based on the current board size chosen by the user(SIZE). I have tried different loops but can't get it to work. Right now it will only work with a 3x3 board.
I am still learning c++ and I have been stuck on this for a few days so I'm hoping a friendly person can help. This is my full program so far, hope it's not too much of a mess!
#include <iostream>
using namespace std;
struct TicTacToe
{
char **board;
};
void makeBoard(TicTacToe&);
void deallocBoard(TicTacToe&);
void printBoard(TicTacToe);
bool isDraw(TicTacToe);
void convertInput(char, char, int&, int&);
char winMove(TicTacToe, int, int);
bool validateSIZE(int);
int SIZE = 1;
int main(){
while(SIZE < 3 || SIZE > 9)
{
cout << "Enter number between 3 and 9 for the length of board.\n";
cout << "Example: 4 will make a board with 4 rows and 4 columns: ";
cin >> SIZE;
validateSIZE(SIZE);
}
TicTacToe game;
makeBoard(game);
char winner = 0;
char turn = 'X';
char rowIn, colIn;
int row, column;
while(!winner && !isDraw(game))
{
printBoard(game);
cout << "\nPlayer " << turn << "'s move (input format: a1): ";
cin >> rowIn >> colIn;
convertInput(rowIn, colIn, row, column);
if (game.board[row][column]==' ')
{
game.board[row][column] = turn;
if (turn == 'X')
{turn = 'O';}
else
{turn = 'X';}
winner = winMove(game, row, column);
}
else
cout << "Taken, try again!\n";
}
printBoard(game);
if (winner == 'X' || winner == 'O')
{cout << " Congrats, the winner is " << winner << '.' << endl;}
else
{cout << " Game ends in a draw." << endl;}
cout << endl << "Game Over!" << endl << endl;
deallocBoard(game);
return 0;
}
// Need help with this function.
char winMove(TicTacToe gameIn, int i, int j)
{
//row win
if (gameIn.board[i][0]==gameIn.board[i][1] &&
gameIn.board[i][0]==gameIn.board[i][2])
{
return gameIn.board[i][j];
}
//column win
if (gameIn.board[0][j]==gameIn.board[1][j] &&
gameIn.board[0][j]==gameIn.board[2][j])
{
return gameIn.board[i][j];
}
//left diagonal win
if (gameIn.board[0][0] != ' ' &&
gameIn.board[0][0] == gameIn.board[1][1] &&
gameIn.board[0][0] == gameIn.board[2][2])
{
return gameIn.board[i][j];
}
//right diagonal win
if (gameIn.board[0][2] != ' ' &&
gameIn.board[0][2] == gameIn.board[1][1] &&
gameIn.board[0][2] == gameIn.board[2][0])
{
return gameIn.board[i][j];
}
return 0;
}
bool validateSIZE(int SIZE)
{
if(SIZE < 3 || SIZE > 9)
{
cout << "\n\nNumber must be between 3 and 9!\nTry again!\nPlease ";
return false;
}
return true;
};
void makeBoard(TicTacToe& gameIn)
{
gameIn.board = new char*[SIZE];
for(int i = 0; i < SIZE; i++)
{gameIn.board[i] = new char[SIZE];}
for(int j =0; j < SIZE; j++)
for(int k = 0; k < SIZE; k++)
{gameIn.board[j][k] = ' ';}
}
void deallocBoard(TicTacToe& gameIn)
{
for(int i = 0; i < SIZE; i++)
delete [] gameIn.board[i];
delete [] gameIn.board;
gameIn.board = NULL;
}
void printBoard(TicTacToe gameIn)
{
int temp = 1;
cout << " ";
while(temp < SIZE + 1)
{
cout << temp << " ";
temp++;
}
temp = 1;
cout << endl;
for(int i = 0; i < SIZE; i++)
{
cout << char(i + 'a') << '|';
for(int j = 0; j < SIZE; j++)
{
cout << gameIn.board[i][j] << '|';
}
cout << endl;
}
}
bool isDraw(TicTacToe gameIn)
{
bool full = true;
for(int i = 0; full && i < SIZE; i++)
for(int j = 0; full && j < SIZE; j++)
full = gameIn.board[i][j] != ' ';
return full;
}
void convertInput(char rowIn, char colIn, int& row, int& column)
{
row = toupper(rowIn) - 'A';
column = colIn - '1';
}
You can easily use 2 for loops to iterate every starting point and its direction to preform victory checking. Something that would look like this:
// hor ver diagonals
// dx[4] = {1, 0, 1, 1};
// dy[4] = {0, 1, 1, -1};
// check horizontal win
for(int i = 0; i < SIZE; ++i)
{
bool win = true;
for(int j = 1; j < SIZE; ++j)
{
if(gameIn.board[j][i] != gameIn.board[j - 1][i])
{
win = false;
break;
}
}
if(win == true){return ;}
}
// check vertical win
.
.
.
// check diagonal 1 win
for(int i = 1; i < SIZE; ++i)
{
if(gameIn.board[i][i] != gameIn.board[i - 1][i - 1])
break;
if(i == SIZE - 1)return ;
}
// check diagonal 2 win
for(int i = 1; i < SIZE; ++i)
{
if(gameIn.board[i][SIZE - i - 1] != gameIn.board[i - 1][SIZE - i])
break;
if(i == SIZE - 1)return ;
}
I'll leave the vertical win for you.

all possible combinations to divide pack of candies

I have problem to solve and I'm stuck, I don't know how to start.
Suppose I have R childrens and S candies. I want to divide candies between childrens. Each child can get 0, 1, 2, 3 or 4 candies. How to find all the possibilities of such a division?
#include <iostream>
using namespace std;
void solve(int r, int s) {
if (s == 0)
{
cout << "no more candies" << endl;
return;
}
if (r == 0)
{
cout << "last child" << endl;
return;
}
for (int j = 0; j < 4 && j <= s; ++j)
{
cout << "r: " << r << " j: " << j << endl;
solve(r-1, s - j);
}
}
int main () {
int r, s;
cin >> r >> s;
solve(r, s);
return 0;
}
For now I have sth like this, I see in output that I have solutions here, but I don't know how to grab and store all possibilities into for example vector.
Just store counts and save variants at the last recursion level
vector<int> counts;
vector<vector<int>> sol;
void solve(int r, int s) {
if (s == 0)
{
sol.push_back(counts);
return;
}
if (r == 0)
{
return;
}
for (int j = 0; j <= 4 && j <= s; ++j)
{
counts[r - 1] += j;
solve(r - 1, s - j);
counts[r - 1] -= j;
}
}
int main() {
int r, s;
r = 3;
s = 5;
for (int j = 0; j < r; ++j)
counts.push_back(0);
solve(r, s);
for (int i = 0; i < sol.size(); i++) {
for (int j = 0; j < sol[i].size(); j++) {
cout << sol[i][j] << ' ';
}
cout << endl;
}
return 0;
}

implantation of RSA algorithm in c++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am working on a project to implement RSA algorithm in c++ and i have no idea about c++ before but I'm still learning,
My question in RSA is how to encode characters to numbers from 0-25:
a encode to 0,
b to 1,
c to 2,
.
.
z to 25,
here is my code:
/*
* C++ Program to Implement the RSA Algorithm
*/
#include<iostream>
#include<math.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
long int p, q, n, t, flag, e[100], d[100], temp[100], j, m[100], en[100], i;
char msg[100];
int prime(long int);
void ce();
long int cd(long int);
void encrypt();
void decrypt();
int prime(long int pr)
{
int i;
j = sqrt(pr);
for (i = 2; i <= j; i++)
{
if (pr % i == 0)
return 0;
}
return 1;
}
int main()
{
cout << "\nENTER FIRST PRIME NUMBER\n";
cin >> p;
flag = prime(p);
if (flag == 0)
{
cout << "\nWRONG INPUT\n";
exit(1);
}
cout << "\nENTER ANOTHER PRIME NUMBER\n";
cin >> q;
flag = prime(q);
if (flag == 0 || p == q)
{
cout << "\nWRONG INPUT\n";
exit(1);
}
cout << "\nENTER MESSAGE\n";
fflush(stdin);
cin >> msg;
for (i = 0; msg[i] != NULL; i++)
m[i] = msg[i];
n = p * q;
t = (p - 1) * (q - 1);
ce();
cout << "\nPOSSIBLE VALUES OF e AND d ARE\n";
for (i = 0; i < j - 1; i++)
cout << e[i] << "\t" << d[i] << "\n";
encrypt();
decrypt();
return 0;
}
void ce()
{
int k;
k = 0;
for (i = 2; i < t; i++)
{
if (t % i == 0)
continue;
flag = prime(i);
if (flag == 1 && i != p && i != q)
{
e[k] = i;
flag = cd(e[k]);
if (flag > 0)
{
d[k] = flag;
k++;
}
if (k == 99)
break;
}
}
}
long int cd(long int x)
{
long int k = 1;
while (1)
{
k = k + t;
if (k % x == 0)
return (k / x);
}
}
void encrypt()
{
long int pt, ct, key = e[0], k, len;
i = 0;
len = strlen(msg);
while (i != len)
{
pt = m[i];
pt = pt - 96;
k = 1;
for (j = 0; j < key; j++)
{
k = k * pt;
k = k % n;
}
temp[i] = k;
ct = k + 96;
en[i] = ct;
i++;
}
en[i] = -1;
cout << "\nTHE ENCRYPTED MESSAGE IS\n";
for (i = 0; en[i] != -1; i++)
printf("%c", en[i]);
}
void decrypt()
{
long int pt, ct, key = d[0], k;
i = 0;
while (en[i] != -1)
{
ct = temp[i];
k = 1;
for (j = 0; j < key; j++)
{
k = k * ct;
k = k % n;
}
pt = k + 96;
m[i] = pt;
i++;
}
m[i] = -1;
cout << "\nTHE DECRYPTED MESSAGE IS\n";
for (i = 0; m[i] != -1; i++)
printf("%c", m[i]);
}
Not sure I get your question right but my bet is you're asking how to convert between ASCII and number representation of characters.
Encoding/Decoding has nothing to do with RSA. You just use dynamic range shift. As the alphabet is in increasing order in ASCII so the only thing left is to offset the a or A to zero.
for lowercase char to number conversion try:
char c='m'; // c is you character m for example
int i=c-`a`; // i is output number
if you got both lowercase and uppercase letters then you need to change it to :
char c='q'; // c is you character q for example
int i; // i is output number
if ((c>='a')&&(c<='z')) i=c-'a';
else i=c-'A';`
where c is your character and i is output number
For number to char conversion try:
c=i+`a`;
or for uppercase:
c=i+`A`;

Clearing the terminal screen

#include <iostream>
#include <math.h>
#include <cstdlib>
using namespace std;
void circle(int x, int y, int radius);
void line(int a, int b, int c, int d);
bool buffer[26][81];
char drawSpace[26][81];
int main() {
int a = 0;
int b = 0;
int c = 0;
int d = 0;
int x = 0;
int y = 0;
int radius = 0;
char choice;
cout << "Type 'c' to draw a circle or type 'l' to draw a line." << endl;
cin >> choice;
if (choice == 'c'){
cout << "please enter an x coordinate for the center of the circle \n";
cin >> x;
cout << "please enter a y coordinate for the center of the circle \n";
cin >> y;
cout << "please enter a value for the radius of the circle \n";
cin >> radius;
int moves = (x - radius) / 10;
for (int s = 0; s < moves; s++){
circle(x, y, radius);
system("clear");
x = x -10;
}
}
else if (choice == 'l'){
cout << "Please enter the x coordinate for the first point on the line \n";
cin >> a;
cout << "Please enter the y coordinate for the first point on the line \n";
cin >> b;
cout << "Please enter the x coordinate for the end point on the line \n";
cin >> c;
cout << "Please enter the y coordinate for the end point on the line \n";
cin >> d;
}
else
cout << "you did not enter an appropriate letter, please restart the program and try again."<< endl;
return 0;
}
void circle(int x, int y, int radius){
if (x + radius >= 81|| x - radius <= 0 || y + radius >= 26 || y - radius <= 0){
cout << "the coordinates provided for the circle will not fit on the screen" << endl;
return;
}
for (int i = 0; i < 26; i++) {
for(int j = 0; j < 81; j++) {
int a = abs (x - j);
int b = abs (y - i);
int distance = pow(a, 2) + pow(b, 2);
int realDistance = pow(radius, 2);
if (abs(realDistance - distance) <= 3){
buffer[i][j] = true;
}
}
}
for (int m = 0; m < 26; m++){
for(int n = 0; n < 81; n++){
if (buffer[m][n]){
drawSpace[m][n] = 42;
}
else
drawSpace[m][n] = 32;
}
}
for (int row = 25; row >= 0; row--) {
for (int col = 0; col < 81; col++) {
cout << drawSpace[row][col];
}
cout << "\n";
}
}
void line(int a, int b, int c, int d){
if (a >= 81 || c >= 81 || a <= 0 || c <= 0 || b >= 26 || d >= 26 || b <= 0 || d <= 0){
return;
}
int intercept = 0;
double rise = d - b;
double run = c - a;
double slope = rise/run;
intercept = b - (slope*a);
for (int i = 0; i < 26; i++) {
for(int j = 21; j < 81; j++) {
if (slope > 0){
if (j > a && j < c){
int newIntercept = i - (slope*j);
int test = abs (intercept - newIntercept);
if (test <= 0)
buffer[i][j] = true;
else
buffer[i][j] = false;
}
}
else if (slope < 0){
if (j < a && j > c){
int newIntercept = i - (slope*j);
int test = abs (newIntercept - intercept);
if (test <= 0)
buffer[i][j] = true;
}
else
break;
}
}
}
for (int m = 0; m < 26; m++){
for(int n = 0; n < 81; n++){
if (buffer[m][n])
drawSpace[m][n] = 42;
else
drawSpace[m][n] = 32;
}
}
for (int row = 25; row >= 0; row--) {
for (int col = 0; col < 81; col++) {
cout << drawSpace[row][col];
}
cout << "\n";
}
}
I have written this code for a programming assignment, the goal of which is to take inputs for the coordinates and dimensions of a circle or line, and to print them out to the terminal as if it were a graph. The second step is to get the shape to move from the right side of the screen to the left. I have started to write this code for the circle, however for some reason the system("clear") call does not seem to clear the screen, and it simply prints extra circles without getting rid of the older one. If someone could help I would really appreciate it.
Try:
cout << "\033[2J\033[1;1H";
Go http://en.wikipedia.org/wiki/ANSI_escape_code for more information.
On Linux (and other Unixes) you could also use the ncurses library to output to a terminal.
The original poster doesn't have enough rep yet, so I'm posting this here for him:
I was actually a bit off base. The system("clear") I was using actually did
work, the problem I was encountering was that I did not reset the bool
array I was using to plot out the points that needed to be drawn.
Thanks for the help, I learned a few things about how to clear the screen before I found my own problem.

Work with arrays

I'm writing some game at c++. The problem is with arrays. It always shows the 'desk' with points (empty parts). Need comments are in the code:
void showDesk(int someArray[][3])
{
for(int i = 0; i < 3 ;i++)
{
for (int j = 0; j < 3; j++)
{
if(someArray [i][j] == 0) cout << ".";
else if (someArray[i][j] == 1) cout << "x";
else if (someArray[i][j] == 2) cout << "o";
}
cout<<"\n";
}
}
void newDesk (int someArray[][3])
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
someArray [i][j] = 0;
}
bool empty(int someArray[][3], int x, int y)
{
if (someArray[x][y] == 0)
return true; // It returns true
else
return false;
}
void setMark(int someArray[][3],int x,int y,int mark)
{
if (empty(someArray,x,y))
someArray [x][y] == mark; // But this never calls!
}
int main(int argc, char** argv) {
int x,y;
int mark;
int someArray [3][3];
newDesk(someArray);
showDesk(someArray);
cout << "------------------\n";
while (true)
{
cout<< "put x,y\n";
cin >> x>>y;
cout << "put mark\n";
cin >> mark;
setMark(someArray,x,y,mark);
showDesk(someArray);
}
return 0;
}
== is comparison, = is assignment.
Your line:
someArray [x][y] == mark;
Does nothing. It should be:
someArray [x][y] = mark;
someArray [x][y] == mark tests the array to see if its equal to mark, but never actually sets it to anything...