Read access violation of std::shared_ptr - visual-studio

I'm working on a personal project using SFML and C++. The project has an interface and some buttons. So... I have a SortingAlgorithms class, which will be a base class and a subclass BubbleSort
class SortingAlgorithms
{
protected:
std::vector<sf::RectangleShape> sequence;
sf::RenderWindow& window;
int minimum, maximum;
int elements;
public:
SortingAlgorithms();
// Class constructor which initializes a sequence
SortingAlgorithms(int min, int max, int els, sf::RenderWindow& win);
std::vector<sf::RectangleShape> GetSequence() const;
// A pure virtual function for overriding
virtual void Sort(std::unique_ptr<Interface>& init) = 0;
// A method for printing the sequence
void Print(std::unique_ptr<Interface>& init);
};
class BubbleSort : public SortingAlgorithms
{
public:
BubbleSort(int min, int max, int els, sf::RenderWindow& win);
void Sort(std::unique_ptr<Interface>& init);
};
The main problem is in the Sort method which has some button events too. What I am trying to do in this method is simply printing a sequence or a sorted sequence using an std::shared_ptr(generatedAlg) which will be initialized on this branch if (selectedAlg == "Bubble Sort"); everything works fine but if it gets to this point if ((*it).DetectButton(window) == true && (*it).GetButton() == "Sort") I get
Exception thrown: read access violation.
std::shared_ptr<SortingAlgorithms>::operator-><SortingAlgorithms,0>(...) returned nullptr.
Similarly happens when I try to allocate it manually too :
Run-Time Check Failure #3 - The variable 'generatedAlg' is being used without being initialized.
Is there any way to solve this issue?
void Interface::ConfigBar(std::unique_ptr<Interface>& init)
{
while (window.isOpen())
{
sf::Event event;
std::shared_ptr<SortingAlgorithms> generatedAlg;
while (window.pollEvent(event))
{
for (std::vector<Button>::iterator it = configButtons.begin(); it != configButtons.end(); it = std::next(it))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
case sf::Event::MouseMoved:
if ((*it).DetectButton(window) == true)
{
(*it).SetTextColor(sf::Color::White);
}
else
{
(*it).SetTextColor(sf::Color::Black);
}
break;
case sf::Event::MouseButtonPressed:
if ((*it).DetectButton(window) == true && (std::distance(configButtons.begin(), it) != 5 && std::distance(configButtons.begin(), it) != 6 && std::distance(configButtons.begin(), it) != 9))
{
(*it).SetShapeColor(sf::Color(0, 109, 119));
}
break;
case sf::Event::MouseButtonReleased:
if ((*it).DetectButton(window) == true && (std::distance(configButtons.begin(), it) != 5 && std::distance(configButtons.begin(), it) != 6 && std::distance(configButtons.begin(), it) != 9))
{
(*it).SetTextColor(sf::Color::Black);
(*it).SetShapeColor(sf::Color(42, 157, 143));
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == ">")
{
inputMin += 10;
configButtons.at(5).SetButton(std::to_string(inputMin));
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == "<")
{
inputMax += 10;
configButtons.at(6).SetButton(std::to_string(inputMax));
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == "+")
{
inputEls += 1;
configButtons.at(9).SetButton(std::to_string(inputEls));
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == "-")
{
inputEls -= 1;
if (inputEls < 0)
{
inputEls = 0;
std::cerr << "Cannot be less than 0" << std::endl;
}
configButtons.at(9).SetButton(std::to_string(inputEls));
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == "Reset")
{
inputMin = 0;
inputMax = 0;
inputEls = 0;
configButtons.at(5).SetButton(std::to_string(inputMin));
configButtons.at(6).SetButton(std::to_string(inputMax));
configButtons.at(9).SetButton(std::to_string(inputEls));
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == "Generate")
{
if (inputMin == 0 || inputMax == 0 || inputEls == 0)
{
std::cout << "Cannot generate a sequence by default configuration" << std::endl;
break;
}
if (selectedAlg == "Bubble Sort")
{
generatedAlg = std::make_shared<BubbleSort>(inputMin, inputMax, inputEls, window);
generatedAlg->Print(init);
}
std::cout << "Sequence generated" << std::endl;
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == "Sort")
{
//generatedAlg = std::make_shared<BubbleSort>(inputMin, inputMax, inputEls, window);
generatedAlg->Sort(init);
std::cout << "The sequence is now sorted" << std::endl;
}
case sf::Event::KeyPressed:
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
{
if (algorithmType == "Sorting Algorithms")
SortingAlgMenu(init);
PathAlgMenu(init);
}
break;
default:
break;
}
}
}
window.clear(sf::Color(sf::Color::White));
for (std::vector<Button>::iterator it = configButtons.begin(); it != configButtons.end(); it = std::next(it))
{
(*it).Draw(window);
}
window.display();
}
}

Related

minmax algorithm with tictactoe, wrong decision

I have this code written in Dart that implements the minmax algorithm, With a tic-tac-toe, the computer is playing as "O" and trying to maximize the score, but I get some wrong decision like this, it says (look at the top, the first is the move coordinate and the second is the score) that I have to move in (0,2). But this is not the right decision.
This is my code:
class Ai {
play(state) {
return max_Value(state);
}
// the action parameter holds the move that got as to this state
List max_Value(List state, {action}) {
List v = [null, double.negativeInfinity];
if (terminal(state)) {
return [action, utility(state)];
}
for (var action in actions(state)) {
if (v[1] == 1) return v;
v = max(v, min_Value(result(state, action), action: action));
}
return v;
}
List min_Value(List state, {action}) {
List v = [null, double.infinity];
if (terminal(state)) {
return [action, utility(state)];
}
for (var action in actions(state)) {
if (v[1] == -1) return v;
v = min(v, max_Value(result(state, action), action: action));
}
return v;
}
List min(List prv, List curr) {
return prv[1] < curr[1] ? prv : curr;
}
List max(List prv, List curr) {
return prv[1] > curr[1] ? prv : curr;
}
bool terminal(List state) {
if (state[0][0] == state[0][1] &&
state[0][0] == state[0][2] &&
state[0][0] != "") {
return true;
}
if (state[1][0] == state[1][1] &&
state[1][0] == state[1][2] &&
state[1][0] != "") {
return true;
}
if (state[2][0] == state[2][1] &&
state[2][0] == state[2][2] &&
state[2][0] != "") {
return true;
}
// vertical
if (state[0][0] == state[1][0] &&
state[0][0] == state[2][0] &&
state[0][0] != "") {
return true;
}
if (state[0][1] == state[1][1] &&
state[0][1] == state[2][1] &&
state[0][1] != "") {
return true;
}
if (state[0][2] == state[1][2] &&
state[0][2] == state[2][2] &&
state[0][2] != "") {
return true;
}
// diagonal
if (state[0][0] == state[1][1] &&
state[2][2] == state[0][0] &&
state[0][0] != "") {
return true;
}
if (state[2][0] == state[1][1] &&
state[2][0] == state[0][2] &&
state[2][0] != "") {
return true;
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (state[i][j] == "") {
return false;
}
}
}
return true;
}
double utility(List state) {
String winner = "";
// horizontal
if (state[0][0] == state[0][1] && state[0][0] == state[0][2]) {
winner = state[0][0];
}
if (state[1][0] == state[1][1] && state[1][0] == state[1][2]) {
winner = state[1][0];
}
if (state[2][0] == state[2][1] && state[2][0] == state[2][2]) {
winner = state[2][0];
}
// vertical
if (state[0][0] == state[1][0] && state[0][0] == state[2][0]) {
winner = state[0][0];
}
if (state[0][1] == state[1][1] && state[0][1] == state[2][1]) {
winner = state[0][1];
}
if (state[0][2] == state[1][2] && state[0][2] == state[2][2]) {
winner = state[0][2];
}
// diagonal
if (state[0][0] == state[1][1] && state[2][2] == state[0][0]) {
winner = state[0][0];
}
if (state[2][0] == state[1][1] && state[2][0] == state[0][2]) {
winner = state[2][0];
}
if (winner == "O") {
return 1;
} else if (winner == "X") {
return -1;
} else {
return 0;
}
}
List actions(List state) {
List acs = [];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (state[i][j] == "") {
acs.add([i, j]);
}
}
}
return acs;
}
List result(List state, List action) {
List newState = [
["", "", ""],
["", "", ""],
["", "", ""]
];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
newState[i][j] = state[i][j];
}
}
newState[action[0]][action[1]] = player(state);
return newState;
}
player(List state) {
int xnum = 0;
int onum = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (state[i][j] == "X") {
xnum++;
} else if (state[i][j] == "O") {
onum++;
}
}
}
if (xnum > onum) {
return "O";
} else {
return "X";
}
}
}
Some mistakes:
This needs to depend on the player to move whether you return max or min:
play(state) {
return max_Value(state);
}
Here (and same for min) v might become an action done later and not the actual action that was performed and lead to the better value.
v = max(v, min_Value(result(state, action), action: action));
Possible improvements:
With a little modification terminal could return the evaluation too and then you don't need the utility function.
You constantly evaluate player with the function. You should have to do that at most once (see first mistake). min and max know whether they are playing X or O. Everything could be simplified a lot and the number of functions reduced without increasing their complexity.

Delete smallest node in a linkedlist

I have an assignment to delete the smallest node in a linked list. I wrote the function minelement for this, but it doesn't delete the smallest node. It just deletes all nodes... why does that happen?
My code:
#include <iostream>
#include <string>
using namespace std;
class linkedlist {
private:
struct node {
int item;
node* next;
};
node* first;
node* last;
int count;
public:
linkedlist()
{
first = last = NULL;
count = 0;
}
bool isempty()
{
return (first == NULL);
}
void insertnode(int value) {
node* newNode = new node;
newNode->item = value;
if (count == 0)
{
first = last = newNode;
newNode->next = NULL;
}
else
{
newNode->next = first;
first = newNode;
}
count++;
}
void insertfromLast(int value)
{
node* newNODE = new node;
newNODE->item = value;
if (count == 0)
{
first = last = newNODE;
newNODE->next = NULL;
}
else
{
last->next = newNODE;
newNODE->next = NULL;
last = newNODE;
}
}
void removefirst()
{
node* curr = first;
if (count == 0)
{
cout << "empty list cannot be deleted" << endl;
}
else if (count == 1)
{
delete first;
last = first = NULL;
count--;
}
else
{
first = first->next;
delete curr;
count--;
}
}
void removelast()
{
if (count == 0)
{
cout << "empty list cannot be deleted" << endl;
}
else if (count == 1)
{
delete first;
last = first = NULL;
count--;
}
else
{
node* curr = first->next;
node* prev = first;
while (curr != last)
{
prev = curr;
curr = curr->next;
}
delete curr;
prev->next = NULL;
last = prev;
count--;
}
}
void position(int pos)
{
node* curr = first;
if (count == 0)
{
cout << "Element's positon cannot be found" << endl;
}
else
{
if (pos > count||pos<0)
{
cout << "Out of range so we can't return info of kth element" << endl;
}
else
{
for (int i = 0; i < pos; i++)
{
curr = curr->next;
}
cout << curr->item;
}
count++;
}
}
void remove_existed_element(int element)
{
if (count == 0)
{
cout << "Empty list cannot be deleted" << endl;
}
node* curr = first->next;
node* prev = first;
if (first->item == element)
{
curr = first;
first = first->next;
delete curr;
count--;
}
else
{
while (curr != NULL)
{
if (curr->item == element)
{
break;
}
prev = curr;
curr = curr->next;
}
if (curr == NULL)
{
cout << "Element cannot be found to delete" << endl;
}
else
{
prev->next = curr->next;
delete curr;
count--;
}
}
}
void maxelement()
{
int max = first->item;
node* curr = first->next;
while (curr != NULL)
{
if (curr->item > max)
{
max = curr->item;
}
curr = curr->next;
}
cout << "MAX ELEMENT IS " << max << endl;
count++;
}
void minelement()
{
int min = first->item;
node* curr = first->next;
node* prev = first;
if (isempty())
{
cout << "Empty linked list cannot be deleted" << endl;
}
else if (count == 1)
{
delete first;
count--;
}
else
{
while (curr != NULL)
{
if (min > curr->item)
{
min = curr->item;
}
curr = curr->next;
}
while (curr->item != min) //10 6 5 2//
{
prev = curr;
curr=curr->next;
}
prev->next = curr->next;// prev->next=NULL;
delete (curr);
count--;
}
}
void print()
{
node* curr = first;
while (curr != NULL)
{
cout << curr->item << " ";
curr = curr->next;
}
cout << endl;
}
};
int main()
{
linkedlist l;
l.insertnode(2);
l.insertnode(5);
l.insertnode(6);
l.insertnode(10);
l.minelement();
l.print();
}
Some of the issues:
curr is dereferenced when it is certain that it is NULL:
while (curr != NULL)
{
if (min > curr->item)
{
min = curr->item;
}
curr = curr->next;
}
while (curr->item != min) // <-- curr will be NULL!!!
the function starts with dereferencing first, which is not safe: when the list is empty this will be an invalid reference. So the first thing to do is to check whether the list is empty.
When count == 1, the first member is not set to NULL, ...etc. But since you already have that logic elsewhere, just call removefirst()
It is a pity that you have 2 loops: one to find what is the minimum value, and another to find the node that precedes that minimum value. You should do both in one loop.
Here is the updated function:
void minelement()
{
if (isempty()) // Check this first!
{
cout << "Empty linked list cannot be deleted" << endl;
}
else if (count == 1)
{
removefirst(); // Use your method
}
else
{
// Only access first members when it is safe:
int min = first->item;
node* beforemin = NULL;
node* curr = first->next;
node* prev = first;
while (curr != NULL)
{
if (min > curr->item)
{
min = curr->item;
// Remember where you found it
beforemin = prev;
}
prev = curr; // keep updated
curr = curr->next;
}
if (beforemin == NULL) {
removefirst();
} else if (beforemin->next == NULL) {
removelast();
} else {
curr = beforemin->next;
beforemin->next = curr->next;
delete (curr);
count--;
}
}
}
Unrelated to your question, but you should obviously also update the maxelement function. The position function has some issues too, like:
count++; should not occur there.
pos > count should really be pos >= count, because you seem to use position 0 for the head node, and so the last node has position count-1.
Finally, try to avoid code duplication. There are too many places where you delete and update count. Try to centralise such common code in a method and call it where needed.

Red-Black Tree Deletion Partially Working

I implemented a red black tree in c++ with find, insert and delete. The delete only works for right side nodes and for the root node. I can't figure out why it isn't working for any of the left side nodes. Here is my code:
Node* searchNode(Node* root, int value){
Node* temp = root;
while (temp != NULL){
if (temp->val == value){
return temp;
}
else if (temp->val < value){
temp = temp->right;
}
else if (temp->val > value){
temp = temp->left;
}
}
}
Node* sibling(Node* node){
if ((node == NULL) || (node->parent == NULL)){
return NULL;
}
if (node == node->parent->left){
return node->parent->right;
}
else{
return node->parent->left;
}
}
Node* maxNode(Node* node){
while (node->right != NULL){
node = node->left;
}
return node;
}
void replaceNode(Node* old, Node* new_node){
if (old->parent == NULL){
old = new_node;
}
else{
if (old == old->parent->left){
old->parent->left = new_node;
}
else{
old->parent->right = new_node;
}
}
if (new_node != NULL){
new_node->parent = old->parent;
}
}
void deleteNode(Node* root, int value){
Node* child;
Node* temp = searchNode(root, value);
if (temp == NULL){
return;
}
if (temp->left != NULL&&temp->right != NULL){
Node* pred = maxNode(temp->right);
temp->val = pred->val;
temp = pred;
}
if (temp->left == NULL || temp->right == NULL){
if (temp->right == NULL && temp->left == NULL){
child = temp;
}
else if (temp->right == NULL){
child = temp->left;
}
else{
child = temp->right;
}
}
if (temp->color == 1){
temp->color = child->color;
delete_case1(root, child);
}
replaceNode(temp, child);
delete temp;
}
void delete_case6(Node* root, Node* n)
{
Node *s = sibling(n);
s->color = n->parent->color;
n->parent->color = 1;
if (n == n->parent->left) {
s->right->color = 1;
rotate_left(root, n->parent);
}
else {
s->left->color = 1;
rotate_right(root, n->parent);
}
}
void delete_case5(Node* root, Node* n)
{
Node *s = sibling(n);
if (s->color == 1) {
if ((n == n->parent->left) &&(s->right->color == 1) &&(s->left->color == 0)) {
s->color = 0;
s->left->color = 1;
rotate_right(root, s);
}else if ((n == n->parent->right) &&(s->left->color == 1) &&(s->right->color == 0)) {
s->color = 0;
s->right->color = 1;
rotate_left(root, s);
}
}
delete_case6(root, n);
}
void delete_case4(Node* root, Node* n)
{
Node *s = sibling(n);
if ((n->parent->color == 0) && (s->color == 1) && (s->left->color == 1) && (s->right->color == 1)) {
s->color = 0;
n->parent->color = 1;
}
else{
delete_case5(root, n);
}
}
void delete_case3(Node* root, Node* n){
Node* s = sibling(n);
if ((n->parent->color == 1) &&(s->color == 1) &&(s->left->color == 1) &&(s->right->color == 1)) {
s->color = 0;
delete_case1(root, n->parent);
}
else
delete_case4(root, n);
}
void delete_case2(Node* root, Node* n){
Node *s = sibling(n);
if (s->color == 0){
n->parent->color = 0;
s->color = 1;
if (n == n->parent->left){
rotate_left(root, n->parent);
}
else if (n == n->parent->right){
rotate_right(root, n->parent);
}
}
delete_case3(root, n);
}
void delete_case1(Node* root,Node* n){
if (n->parent != NULL){
delete_case2(root,n);
}
}
void main(){
ABTree* ABtree=new ABTree;
ABtree->root = NULL;
insertTree(ABtree->root, 15);
insertTree(ABtree->root, 8);
insertTree(ABtree->root, 2);
insertTree(ABtree->root, 9);
insertTree(ABtree->root, 10);
insertTree(ABtree->root, 12);
insertTree(ABtree->root, 18);
insertTree(ABtree->root, 25);
insertTree(ABtree->root, 20);
printTree(ABtree->root);
Node* search=searchNode(ABtree->root, 18);
cout << endl;
cout << search->val<<endl;
deleteNode(ABtree->root, 8);
printTree(ABtree->root);
}
For example if i want to delete either 8/9/2 the program crashes at delete_case4 at the if statement.
Thanks in advance!

Converting Infix to Postfix Using Stack

I'm having trouble creating a program that will convert infix to postfix. My code is as follows:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#define DEFAULT_SIZE 20
/*
*
*/
class Stack {
char *arr;
int tos, capacity;
public:
//Constructors
Stack();
Stack(int size);
//Destructor
~Stack();
//Methods
void push(char a);
char pop();
int get_size();
bool is_empty();
bool is_full();
void display();
char get_top();
};
Stack::Stack() {
arr = new char[DEFAULT_SIZE];
tos = 0;
capacity = DEFAULT_SIZE;
}
Stack::Stack(int size) {
arr = new char[size];
tos = 0;
capacity = size;
}
Stack::~Stack() {
delete[] arr;
}
void Stack::push(char a) {
if (!is_full())
arr[tos++] = a;
else
cout << "Sorry, the stack is full. Push failed!" << endl;
}
char Stack::pop() {
if (!is_empty())
return arr[--tos];
else {
cout << "Sorry, the stack is empty. Pop failed!" << endl;
return -1;
}
}
char Stack::get_top() {
if (!is_empty())
return arr[tos - 1];
else {
cout << "Sorry, the stack is empty. Pop failed!" << endl;
return 'E';
}
}
int Stack::get_size() {
return tos;
}
bool Stack::is_empty() {
if (tos == 0)
return true;
else
return false;
}
bool Stack::is_full() {
if (tos == capacity)
return true;
else
return false;
}
void Stack::display() {
if (tos == 0)
cout << "The stack is empty" << endl;
else {
for (int i = 0; i<tos;i++)
cout << arr[i] << " ";
cout << endl;
}
}
int main() {
Stack stack(50);
string infix = "(1+3)*2/(6-4)^2";
stringstream ss;
for (char c : infix) {
if ('0' <= c && c <= '9') {
ss << c;
}
else if (c == '(') {
continue;
}
else if (c == ')') {
ss << stack.pop();
stack.pop();
}
else if (c == '^' || c == '*' || c == '/' || c == '+' || c == '-') {
stack.push(c);
}
}
string postfix = ss.str();
cout << postfix;
I know what my issue is, I just dont understand or comprehend how to solve it. This code currently outputs 13+264-2. It needs to output 13+2*64-2^/. I know my issues is with my last else if statement in int main(). I dont understand how to rearrange the operators behind the operands.
Anything in parentheses is passed into the stream correctly, because I can wait until the closing parenthesis is hit to add in the operator. I can't visualize how to make that work for things not in parentheses though. Can anyone offer any advice?

Algorithm to determine status of a TicTacToe game?

I have a program that allows 2 players to play TicTacToe. After each player makes a move, it should display the board at that point and return an enumaration called Status that show whether the players should continue, if a player won, or if it's a draw. However, the algorithm either return a StackOverflowError, or continues input. Here is the algorithm I used.
//Checks for winner by rows
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 1; j++) {
if (board[i][j] == 'X') {
if (board[i][j] == board[i][0 + 1] && board[i][j] == board[i][0 + 2]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
} else if (board[i][j] == 'O') {
if (board[i][j] == board[i][0 + 1] && board[i][j] == board[i][0 + 2]) {
printStatus(2);
return Status.WIN;
} else {
return Status.CONTINUE;
}
}
}
}
//Checks for winner by columns
for (int i = 0; i < 1; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == 'X') {
if (board[i][j] == board[0 + 1][j] && board[i][j] == board[0 + 2][j]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
} else if (board[i][j] == 'O') {
if (board[i][j] == board[0 + 1][j] && board[i][j] == board[0 + 2][j]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
}
}
}
//This group of if statements boards for winner diagnolly
if (board[0][0] == 'X') {
if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
}else if (board[0][0] == '0') {
if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
}
if (board[0][2] == 'O') {
if (board[0][2] == board[1][1] && board[0][2] == board[2][0]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
}else if (board[0][2] == 'X') {
if (board[0][2] == board[1][1] && board[0][2] == board[2][0]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
}
Here is the printStatus method.
private void printStatus(int player) {
Status status = gameStatus();
if (status == Status.DRAW) {
System.out.println("The game has ended in a draw.");
System.exit(0);
} else if (status == Status.WIN) {
System.out.println("Player " + player + " has won the game.");
System.exit(0);
} else if (status == Status.CONTINUE) {
System.out.println("The game continues.");
play();
}
}
Here is the error:
Exception in thread "main" java.lang.StackOverflowError
at tictactoe.TicTacToe.gameStatus(TicTacToe.java:86)
at tictactoe.TicTacToe.printStatus(TicTacToe.java:69)
at tictactoe.TicTacToe.gameStatus(TicTacToe.java:92)
at tictactoe.TicTacToe.printStatus(TicTacToe.java:69)
at tictactoe.TicTacToe.gameStatus(TicTacToe.java:92)
at tictactoe.TicTacToe.printStatus(TicTacToe.java:69)
And so forth
Your problem is that you have code that repetitively calls itself creating a never-ending cycle. For example, if method A() has code that calls method B(), but within B(), there is code that calls A(), then the code will run infinitely as A() invokes B(), which then invokes A() again with the cycle repeating. StackOverflow errors are often indicative of this.
In your case, it's because your function gameStatus() (which, I assume is the first part of code you posted), calls printStatus(), which then calls gameStatus() again in the line Status status = gameStatus();
Try passing the status as an argument in printStatus, like printStatus(2,Status.WIN);, instead of trying to get the return of gameStatus within printStatus.
There does not appear to be any code in what you posted that would cause a StackOverflowError (unless you're doing something really weird in printStatus). The error causing that must be somewhere else in your code. So, unfortunately, unless you post more code, I can't help.
However, here are two things I noticed you could use some improvement on. First, (the way you're implementing this) you do not need nested for loops. The loops beginning with for (int j = 0; j < 1; j++) {, and with for (int i = 0; i < 1; i++) {, are not necessary, and they cause errors, as they produce checks where only two boxes are checked, instead of three in a row. You can simplify them by simply eliminating those loops. (I also modified your if statement, see below for more detail).
//Checks for winner by rows
for (int i = 0; i < 3; i++) {
if (board[i][j] == board[i][0 + 1] && board[i][j] == board[i][0 + 2]) { //Check if one player has matched a row
if (board[i][j] == 'X') { //Then check which player won
printStatus(1);
}
else{
printStatus(2);
}
return Status.WIN;
} else {
return Status.CONTINUE;
}
}
You can also simplify your if statement by only checking for whether X or 0 occupy a space, after you have figured out someone won. So, for example, instead of doing
if (board[0][0] == 'X') {
if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
printStatus(1);
}
//More code here
}
else if (board[0][0] == 'O') {
if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
printStatus(1);
}
//More code here
}
You can simply the code by changing it to:
if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) { //Check if first diagonal is complete
if (board[0][0] == 'X') { //Check who won
printStatus(1);
}
else{
printStatus(1);
}
return Status.WIN;
} else {
return Status.CONTINUE;
}
In this way, the statement if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) is only executed once, and the second statement, if (board[0][0] == 'X'), is only executed if someone has won the diagonal. In your implementation, the first check of if (board[0][0] == 'X') will be run, then either the interior if statement, or it will execute the second player check, if (board[0][0] == 'O'), then the interior one. In this way, your code will have to run between 2 and 3 different statements, whereas in mine, it's between 1 and 2 (with two only occurring when a player has won).

Resources