A problem has risen in my OpenGL code which looked so simple but it doesn't seem to work like I expected it to be.
The code is as follows:
int x = 0, y = 0, z = 0, TP = 1;
bool initiate_placement = true;
float trans[3][3][2] = {{{-16.0,16.0},{0.0,16.0},{16.0,16.0}},
{{-16.0,0.0},{0.0,0.0},{16.0,0.0}},
{{-16.0,-16.0},{0,-16.0},{16.0,-16.0}}};
vector<tiles> Place;
tiles VER, HOR, NOREA, NORWE, SOUEA, SOUWE, TNOR, TSOU, TEA, TWE, CRO;
void Tile_Placement()
{
int A = rand() % 10 + 1;
if (TP <= 9)
{
switch (A)
{
case 1:
VER.vertical(trans[x][y][z],trans[x][y][z + 1]);
Place.push_back(VER);
break;
case 2:
HOR.horizontal(trans[x][y][z],trans[x][y][z + 1]);
Place.push_back(HOR);
break;
case 3:
NOREA.north2east(trans[x][y][z],trans[x][y][z + 1]);
Place.push_back(NOREA);
break;
case 4:
NORWE.north2west(trans[x][y][z],trans[x][y][z + 1]);
Place.push_back(NORWE);
break;
case 5:
SOUEA.south2east(trans[x][y][z],trans[x][y][z + 1]);
Place.push_back(SOUEA);
break;
case 6:
SOUWE.south2west(trans[x][y][z],trans[x][y][z + 1]);
Place.push_back(SOUWE);
break;
case 7:
TNOR.T_north(trans[x][y][z],trans[x][y][z + 1]);
Place.push_back(TNOR);
break;
case 8:
TSOU.T_south(trans[x][y][z],trans[x][y][z + 1]);
Place.push_back(TSOU);
break;
case 9:
TEA.T_east(trans[x][y][z],trans[x][y][z + 1]);
Place.push_back(TEA);
break;
case 10:
TWE.T_west(trans[x][y][z],trans[x][y][z + 1]);
Place.push_back(TWE);
break;
case 11:
CRO.cross(trans[x][y][z],trans[x][y][z + 1]);
Place.push_back(CRO);
break;
}
cout << trans[x][y][z] << " , " << trans[x][y][z + 1] << endl;
}
}
void Tile_LoopZ()
{
if (z < 1)
{
Tile_Placement();
TP++;
z++;
Tile_LoopZ();
}
z = 0;
}
void Tile_LoopY()
{
if (y < 3)
{
Tile_LoopZ();
y++;
Tile_LoopY();
}
y = 0;
}
void Tile_LoopX()
{
if (initiate_placement == true)
{
if (x < 3)
{
Tile_LoopY();
x++;
Tile_LoopX();
x = 0;
}
}
initiate_placement = false; //<<< problem is focused here
x = 0, y = 0, z = 0, TP = 1;
}
void gameScene()
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLineWidth(2.0);
glColor3f(1.0, 1.0, 1.0);
Tile_LoopX();
glutSwapBuffers();
}
The code here tells me that in the recursive function Tile_LoopX();, once initiate_placement == true, a code happens that pushes back nine tiles. Once the nine tiles are pushed back, it makes initiate_placement false, that way if gameScene() is called again, Tile_LoopX(); wont be able to run its code.
The things that I know so far is that gameScene() is an infinite loop. Removing initiate_placement = false; makes the tiles randomly spaz out because it's called over and over again. Placing initiate_placement = false; sounds like a good solution but the tiles were never pushed back at all. To test that the code passes through, I added a cout and it actually passes through.
If anything, I might have missed something completely simple and I really need help for it.
UPDATE 4/16/15:
The vectors do get pushed back as I cout'ed the vector's size (which is 9). The problem now lies that the objects within the vector were never visually shown in the program, or even able to use its code within the program.
Related
I'm writing a program for class that basically runs page replacement algorithms 1000 times to show which has fewer average page faults. My problem is with an error I recieve from xmemory.
The code is reduced to areas where the error consistently occurs.
checkFrames() checks an array to see if it already contains the inputString[i].
frames1, frames2, etc. are arrays that the input is being assigned to according to the algorithm, each of size corresponding their number.
randomInputString() is just how it sounds.
constexpr auto INPUTNUM = 10;
list<int> framesLRU;
list<int>::iterator it;
int frames = 1;
void LRU()
{
for (int i = 0; i < INPUTNUM; i++)
{
bool inFrames = checkFrames(inputString[i]);
if (inFrames == true)
{
it = find(framesLRU.begin(), framesLRU.end(), frameRep);
framesLRU.erase(it);
framesLRU.push_back(frameRep);
}
else
{
int frameUpdate = framesLRU.front();
framesLRU.pop_front();
framesLRU.push_back(frameUpdate);
switch (frames)
{
case 1:
frames1[frameUpdate] = inputString[i];
break;
case 2:
frames2[frameUpdate] = inputString[i];
break;
case 3:
frames3[frameUpdate] = inputString[i];
break;
case 4:
frames4[frameUpdate] = inputString[i];
break;
case 5:
frames5[frameUpdate] = inputString[i];
break;
case 6:
frames6[frameUpdate] = inputString[i];
break;
case 7:
frames7[frameUpdate] = inputString[i];
break;
}
pageFaults++;
}
if ((i < frames) && (inputString[i] == 0))
pageFaults++;
}
}
int main()
{
srand(time(NULL));
for (int i = 0; i < 1000; i++)
{
randomInputString();
frames = 1;
do
{
runLRU(i);
frames++;
} while (frames <= 7);
}
printTable();
return 0;
}
The error always happens in the 59th iteration of i in the for loop in main, but within the do while loop it seems random as to when it occurs.
Although it does seem to be happening here:
it = find(framesLRU.begin(), framesLRU.end(), frameRep);
framesLRU.erase(it);
framesLRU.push_back(frameRep);
within the LRU() function. The iteration of i and the value of frames does not seem to be consistent for the error.
Edit: I figured out the problem. It was an error on my part with how I was assigning values in an array.
I'm trying to count the cats and dogs in a string. So,
for example:
if the string is "cc+dd-cd",:
I want to count 2 positive cats, 2 positive dogs, 1 negative cat, 1 negative dog (yes I know this is a weird way to count, but it's part of my assignment).
I thought about doing a for loop where I iterated over the string, then nested inside the for loop, I'd have a while loop that would run until a '-', then run until a '+' or the end. I started the code, and without even getting that far into it, it created an infinite loop.
Question: How can I fix it?
Thanks!
string animalparkString = "cc+dd-cd"
for (int k = 0; k != animalparkString.size(); k++)
{
while (k != '-'){
pdc = pdc + 1; //positive dog count
pcc = pcc + 1; //positive cat count
}
while (k != '+') {
ndc = ndc + 1;
ncc = ncc + 1;
}
}
The immediate issue is that the while loops check k's value, but don't modify it. So once you entered one of them you'll be stuck there infinitely as k doesn't change inside the loop's body.
I wouldn't bother with nested loops - I'd just go over the entire string in one loop, and evaluate each character in its turn. A neat way to accomplish this is to keep a state of whether you're adding or subtracting (according to whether you last encountered a + or a - sign:
bool positive = true;
string animalparkString = "cc+dd-cd";
for (int k = 0; k < animalparkString.size(); k++) {
char ch = animalparkString[k];
switch (ch) {
case '+':
positive = true;
break;
case '-':
positive = false;
break;
case 'c':
if (positive) {
pcc++;
} else {
ncc++
}
break;
case 'd':
if (positive) {
pdc++;
} else {
ndc++
}
break;
}
}
This post describes iterating all characters is a string.
This is a simple solution using modern C++:
int sign = 1;
int dogs_count = 0, cats_count = 0;
std::string animalparkString = "-cccccc+dddd-cd";
for (const char& ch : animalparkString)
{
switch (ch) {
case '+':
sign = 1;
continue;
case '-':
sign = -1;
continue;
case 'c':
cats_count += sign;
continue;
case 'd':
dogs_count += sign;
continue;
}
}
std::cout <<"dogs: " << dogs_count << " cats: " <<cats_count;
A couple of suggestions to help you get started:
1. Use online c++ compilers to quickly test code
2. If your code doesn't behave as expected, use step-by-step debugging in your IDE or print our variables as you go using std::cout
3. Explicitly stating namespace is considered good practice. i.e:
// preferable:
std::string myString;
// avoid:
using namespace std;
string myString
To make your code work without too many changes , you can simply replace the while() condition with an if(). Moreover, instead of checking the iterator value k, you should compare the kth string element animalparkString[k].
Then you might start wondering if the code you wrote is actually doing what you expect. Possible questions you could try to answer is "how do I distinguish between positive or negative counts" and, then, "how do I distinguish between cats and dogs "? You will probably need to check also for cs and ds, not only for the operation sign!
string animalparkString = "cc+dd-cd"
for (int k = 0; k != animalparkString.size(); k++)
{
if(animalparkStrink[k] != '-'){
// Now you know, there will be a pos count. Dog or Cat?
}
if(animalparkString[k] != '+') {
// Now you know, there will be a neg count. Dog or Cat?
}
}
Note that if you write while( k != '-'), it will always evaluate true and, therefore, you will be stuck there. If it is the first time working with for-loops, consider printing the iterator value, to understand when and where you are stuck.
string animalparkString = "cc+dd-cd"
for (int k = 0; k != animalparkString.size(); k++)
{
std::cout << "for-loop iteration number: " << k << std::endl;
if(animalparkStrink[k] != '-'){
// Now you know, there will be a pos count. Dog or Cat?
}
if(animalparkString[k] != '+') {
// Now you know, there will be a neg count. Dog or Cat?
}
}
for and while together approach is unnecessarily complicated. Here's a simpler solution:
#include <concepts>
#include <iostream>
int main() {
auto const& str{"cc+dd-cd"};
std::boolean auto isPositive = 1;
std::integral auto pdc{0}, pcc{0}, ndc{0}, ncc{0};
for (char const ch : str) {
switch (ch) {
case 'c': {
pcc += isPositive;
ncc += !isPositive;
break;
}
case 'd': {
pdc += isPositive;
ndc += !isPositive;
break;
}
case '+': {
isPositive = true;
break;
}
case '-': {
isPositive = false;
break;
}
}
}
std::cout << "pcc: " << pcc << '\n'
<< "ncc: " << ncc << '\n'
<< "pdc: " << pdc << '\n'
<< "ndc: " << ndc << '\n';
}
LIVE
I'm have a small issue with evaluating a straight in a seven card hand, where you want to get the highest 5 card straight.
I can get highest 5 card straight as long as there is not a pair in the hand so for example:
Hole cards: 2h,3d
community cards:4h, 5s, 6s, 8d, 9d,
Output: 2h,3d,4h,5s,6s
Because there is no pair within the straight it counts and outputs just fine.
The problem occurs when there is a pair within the straight
for example:
Hole cards: 2h, 3d,
community cards: 4h, 4c, 5s, 6s, 8d
Output: 2h,3d,4h,4c,5s
So it is counting the pair in the straight, I need a way to skip past one of the paired cards and select only one. This happens with 3 of a kind as well.
It makes complete sense to me why it is doing this, but for the life of me I can't think of a way to fix it.
Here is the function:
bool Player::checkForStraight()
{
//Loops through the ranks from greatest to least 0 is NONE is the enum class
for (int i = FACES; i >= 1; i--)
{
//Checks to see if a straight exists (_checkNumfaces is an array[13] to
//hold the amount of each card
if ((_checkNumFaces[i - 1] >= 1) && (_checkNumFaces[i - 2] >= 1) &&
(_checkNumFaces[i - 3] >= 1) && (_checkNumFaces[i - 4] >= 1) &&
(_checkNumFaces[i - 5] >= 1))
{
//If a straight exists loop through the cards(sorted in another
//function from lowest to highest
for (int j = 6; j >= 0; j--)
{
//if the face matches the enum value of i then we have a
//straight there down because I checked if the straight
//existed already
if ((*p_playerHand[j])->face == (Face)(i))
{
//PlayerHighCards out of the seven
p_playerHighFive[4] = p_playerHand[j];
p_playerHighFive[3] = p_playerHand[j - 1];
p_playerHighFive[2] = p_playerHand[j - 2];
p_playerHighFive[1] = p_playerHand[j - 3];
p_playerHighFive[0] = p_playerHand[j - 4];
return true;
}
}
}
}
return false;
}
Sorry about the shoddy formatting at the bottom but its only curly braces and they are fine in my code.
I know how to check for A,2,3,4,5 straight I just havnt coded yet, I am just really stumped on how to move past one of the pairs that I was on about. Its not just pairs, this occurs with 3 of a kind as well (so if there's 3 of a kind in the straight) or more than one pair for that matter so 2 pairs. Doesn't happen outside of this because there's not physically enough cards to be concerned about it.
Sorry if my code is not that elegant and if there's a better way then let me know. I havnt learned templates or the stl yet as I have only just started the language so a solution not using these would be great.
I tried to be as descriptive as possible but, I'm new to this so if you have any questions just ask:)
Here is the function for counting the different cards in the deck
void Player::countNumFaces(const int& size)
{
for (int i = 0; i < (size); i++)
{
switch((*p_playerHand[i])->face)
{
case Face::NONE: std::cout << "Joker" << std::endl;
case Face::TWO: _checkNumFaces[0] ++; break;
case Face::THREE: _checkNumFaces[1] ++; break;
case Face::FOUR: _checkNumFaces[2] ++; break;
case Face::FIVE: _checkNumFaces[3] ++; break;
case Face::SIX: _checkNumFaces[4] ++; break;
case Face::SEVEN: _checkNumFaces[5] ++; break;
case Face::EIGHT: _checkNumFaces[6] ++; break;
case Face::NINE: _checkNumFaces[7] ++; break;
case Face::TEN: _checkNumFaces[8] ++; break;
case Face::JACK: _checkNumFaces[9] ++; break;
case Face::QUEEN: _checkNumFaces[10] ++; break;
case Face::KING: _checkNumFaces[11] ++; break;
case Face::ACE: _checkNumFaces[12] ++; break;
}
}
std::cout << "| 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 | 10 || J || Q || K || A |" << std::endl; //Print for testing
for (int i = 0; i < FACES; i++) { std::cout << "| " << _checkNumFaces[i] << " |"; } //Print for testing
}
Instead of
p_playerHighFive[4] = p_playerHand[j];
p_playerHighFive[3] = p_playerHand[j - 1];
p_playerHighFive[2] = p_playerHand[j - 2];
p_playerHighFive[1] = p_playerHand[j - 3];
p_playerHighFive[0] = p_playerHand[j - 4];
return true;
try
int k = 4;
int l = 0;
p_playerHighFive[k] = p_playerHand[j-l];
k--;
l++;
while(k>=0)
{
if( isSameValue(p_playerHighFive[k+1], p_playerHand[j-l]) ) //check if card has same value
{
l++;
continue;
}
p_playerHighFive[k] = p_playerHand[j-l];
k--;
l++;
}
I'm making a C++ program for the game chopsticks.
It's a really simple game with only 625 total game states (and it's even lower if you account for symmetry and unreachable states). I have read up minimax and alpha-beta algorithms, mostly for tic tac toe, but the problem I was having was that in tic tac toe it's impossible to loop back to a previous state while that can easily happen in chopsticks. So when running the code it would end up with a stack overflow.
I fixed this by adding flags for previously visited states (I don't know if that's the right way to do it.) so that they can be avoided, but now the problem I have is that the output is not symmetric as expected.
For example in the start state of the game each player has one finger so it's all symmetric. The program tells me that the best move is to hit my right hand with my left but not the opposite.
My source code is -
#include <iostream>
#include <array>
#include <vector>
#include <limits>
std::array<int, 625> t; //Flags for visited states.
std::array<int, 625> f; //Flags for visited states.
int no = 0; //Unused. For debugging.
class gamestate
{
public:
gamestate(int x, bool t) : turn(t) //Constructor.
{
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++) {
val[i][j] = x % 5;
x /= 5;
}
init();
}
void print() //Unused. For debugging.
{
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++)
std::cout << val[i][j] << "\t";
std::cout << "\n";
}
std::cout << "\n";
}
std::array<int, 6> canmove = {{ 1, 1, 1, 1, 1, 1 }}; //List of available moves.
bool isover() //Is the game over.
{
return ended;
}
bool won() //Who won the game.
{
return winner;
}
bool isturn() //Whose turn it is.
{
return turn;
}
std::vector<int> choosemoves() //Choose the best possible moves in the current state.
{
std::vector<int> bestmoves;
if(ended)
return bestmoves;
std::array<int, 6> scores;
int bestscore;
if(turn)
bestscore = std::numeric_limits<int>::min();
else
bestscore = std::numeric_limits<int>::max();
scores.fill(bestscore);
for (int i = 0; i < 6; i++)
if (canmove[i]) {
t.fill(0);
f.fill(0);
gamestate *play = new gamestate(this->playmove(i),!turn);
scores[i] = minimax(play, 0, std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
std::cout<<i<<": "<<scores[i]<<std::endl;
delete play;
if (turn) if (scores[i] > bestscore) bestscore = scores[i];
if (!turn) if (scores[i] < bestscore) bestscore = scores[i];
}
for (int i = 0; i < 6; i++)
if (scores[i] == bestscore)
bestmoves.push_back(i);
return bestmoves;
}
private:
std::array<std::array<int, 2>, 2 > val; //The values of the fingers.
bool turn; //Whose turn it is.
bool ended = false; //Has the game ended.
bool winner; //Who won the game.
void init() //Check if the game has ended and find the available moves.
{
if (!(val[turn][0]) && !(val[turn][1])) {
ended = true;
winner = !turn;
canmove.fill(0);
return;
}
if (!(val[!turn][0]) && !(val[!turn][1])) {
ended = true;
winner = turn;
canmove.fill(0);
return;
}
if (!val[turn][0]) {
canmove[0] = 0;
canmove[1] = 0;
canmove[2] = 0;
if (val[turn][1] % 2)
canmove[5] = 0;
}
if (!val[turn][1]) {
if (val[turn][0] % 2)
canmove[2] = 0;
canmove[3] = 0;
canmove[4] = 0;
canmove[5] = 0;
}
if (!val[!turn][0]) {
canmove[0] = 0;
canmove[3] = 0;
}
if (!val[!turn][1]) {
canmove[1] = 0;
canmove[4] = 0;
}
}
int playmove(int mov) //Play a move to get the next game state.
{
auto newval = val;
switch (mov) {
case 0:
newval[!turn][0] = (newval[turn][0] + newval[!turn][0]);
newval[!turn][0] = (5 > newval[!turn][0]) ? newval[!turn][0] : 0;
break;
case 1:
newval[!turn][1] = (newval[turn][0] + newval[!turn][1]);
newval[!turn][1] = (5 > newval[!turn][1]) ? newval[!turn][1] : 0;
break;
case 2:
if (newval[turn][1]) {
newval[turn][1] = (newval[turn][0] + newval[turn][1]);
newval[turn][1] = (5 > newval[turn][1]) ? newval[turn][1] : 0;
} else {
newval[turn][0] /= 2;
newval[turn][1] = newval[turn][0];
}
break;
case 3:
newval[!turn][0] = (newval[turn][1] + newval[!turn][0]);
newval[!turn][0] = (5 > newval[!turn][0]) ? newval[!turn][0] : 0;
break;
case 4:
newval[!turn][1] = (newval[turn][1] + newval[!turn][1]);
newval[!turn][1] = (5 > newval[!turn][1]) ? newval[!turn][1] : 0;
break;
case 5:
if (newval[turn][0]) {
newval[turn][0] = (newval[turn][1] + newval[turn][0]);
newval[turn][0] = (5 > newval[turn][0]) ? newval[turn][0] : 0;
} else {
newval[turn][1] /= 2;
newval[turn][0] = newval[turn][1];
}
break;
default:
std::cout << "\nInvalid move!\n";
}
int ret = 0;
for (int i = 1; i > -1; i--)
for (int j = 1; j > -1; j--) {
ret+=newval[i][j];
ret*=5;
}
ret/=5;
return ret;
}
static int minimax(gamestate *game, int depth, int alpha, int beta) //Minimax searching function with alpha beta pruning.
{
if (game->isover()) {
if (game->won())
return 1000 - depth;
else
return depth - 1000;
}
if (game->isturn()) {
for (int i = 0; i < 6; i++)
if (game->canmove[i]&&t[game->playmove(i)]!=-1) {
int score;
if(!t[game->playmove(i)]){
t[game->playmove(i)] = -1;
gamestate *play = new gamestate(game->playmove(i),!game->isturn());
score = minimax(play, depth + 1, alpha, beta);
delete play;
t[game->playmove(i)] = score;
}
else
score = t[game->playmove(i)];
if (score > alpha) alpha = score;
if (alpha >= beta) break;
}
return alpha;
} else {
for (int i = 0; i < 6; i++)
if (game->canmove[i]&&f[game->playmove(i)]!=-1) {
int score;
if(!f[game->playmove(i)]){
f[game->playmove(i)] = -1;
gamestate *play = new gamestate(game->playmove(i),!game->isturn());
score = minimax(play, depth + 1, alpha, beta);
delete play;
f[game->playmove(i)] = score;
}
else
score = f[game->playmove(i)];
if (score < beta) beta = score;
if (alpha >= beta) break;
}
return beta;
}
}
};
int main(void)
{
gamestate test(243, true);
auto movelist = test.choosemoves();
for(auto i: movelist)
std::cout<<i<<std::endl;
return 0;
}
I'm passing the moves in a sort of base-5 to decimal system as each hand can have values from 0 to 4.
In the code I have input the state -
3 3
4 1
The output says I should hit my right hand (1) to the opponent's right (3) but it does not say I should hit it to my opponent's left (also 3)
I think the problem is because of the way I handled infinite looping.
What would be the right way to do it? Or if that is the right way, then how do I fix the problem?
Also please let me know how I can improve my code.
Thanks a lot.
Edit:
I have changed my minimax function as follows to ensure that infinite loops are scored above losing but I'm still not getting symmetry. I also made a function to add depth to the score
static float minimax(gamestate *game, int depth, float alpha, float beta) //Minimax searching function with alpha beta pruning.
{
if (game->isover()) {
if (game->won())
return 1000 - std::atan(depth) * 2000 / std::acos(-1);
else
return std::atan(depth) * 2000 / std::acos(-1) - 1000;
}
if (game->isturn()) {
for (int i = 0; i < 6; i++)
if (game->canmove[i]) {
float score;
if(!t[game->playmove(i)]) {
t[game->playmove(i)] = -1001;
gamestate *play = new gamestate(game->playmove(i), !game->isturn());
score = minimax(play, depth + 1, alpha, beta);
delete play;
t[game->playmove(i)] = score;
} else if(t[game->playmove(i)] == -1001)
score = 0;
else
score = adddepth(t[game->playmove(i)], depth);
if (score > alpha) alpha = score;
if (alpha >= beta) break;
}
return alpha;
} else {
for (int i = 0; i < 6; i++)
if (game->canmove[i]) {
float score;
if(!f[game->playmove(i)]) {
f[game->playmove(i)] = -1001;
gamestate *play = new gamestate(game->playmove(i), !game->isturn());
score = minimax(play, depth + 1, alpha, beta);
delete play;
f[game->playmove(i)] = score;
} else if(f[game->playmove(i)] == -1001)
score = 0;
else
score = adddepth(f[game->playmove(i)], depth);
if (score < beta) beta = score;
if (alpha >= beta) break;
}
return beta;
}
}
This is the function to add depth -
float adddepth(float score, int depth) //Add depth to pre-calculated score.
{
int olddepth;
float newscore;
if(score > 0) {
olddepth = std::tan((1000 - score) * std::acos(-1) / 2000);
depth += olddepth;
newscore = 1000 - std::atan(depth) * 2000 / std::acos(-1);
} else {
olddepth = std::tan((1000 + score) * std::acos(-1) / 2000);
depth += olddepth;
newscore = std::atan(depth) * 2000 / std::acos(-1) - 1000;
}
return newscore;
}
Disclaimer: I don't know C++, and I frankly haven't bothered to read the game rules. I have now read the rules, and still stand by what I said...but I still don't know C++. Still, I can present some general knowledge of the algorithm which should set you off in the right direction.
Asymmetry is not in itself a bad thing. If two moves are exactly equivalent, it should choose one of them and not stand helpless like Buridan's ass. You should, in fact, be sure that any agent you write has some method of choosing arbitrarily between policies which it cannot distinguish.
You should think more carefully about the utility scheme implied by refusing to visit previous states. Pursuing an infinite loop is a valid policy, even if your current representation of it will crash the program; maybe the bug is the overflow, not the policy that caused it. If given the choice between losing the game, and refusing to let the game end, which do you want your agent to prefer?
Playing ad infinitum
If you want your agent to avoid losing at all costs -- that is, you want it to prefer indefinite play over loss -- then I would suggest treating any repeated state as a terminal state and assigning it a value somewhere between winning and losing. After all, in a sense it is terminal -- this is the loop the game will enter forever and ever and ever, and the definite result of it is that there is no winner. However, remember that if you are using simple minimax (one utility function, not two), then this implies that your opponent also regards eternal play as a middling result.
It may sound ridiculous, but maybe playing unto infinity is actually a reasonable policy. Remember that minimax assumes the worst case -- a perfectly rational foe whose interests are the exact opposite of yours. But if, for example, you're writing an agent to play against a human, then the human will either err logically, or will eventually decide they would rather end the game by losing -- so your agent will benefit from patiently staying in this Nash equilibrium loop!
Alright, let's end the game already
If you want your agent to prefer that the game end eventually, then I would suggest implementing a living penalty -- a modifier added to your utility which decreases as a function of time (be it asymptotic or without bound). Implemented carefully, this can guarantee that, eventually, any end is preferable to another turn. With this solution as well, you need to be careful about considering what preferences this implies for your opponent.
A third way
Another common solution is to depth-limit your search and implement an evaluation function. This takes the game state as its input and just spits out a utility value which is its best guess at the end result. Is this provably optimal? No, not unless your evaluation function is just completing the minimax, but it means your algorithm will finish within a reasonable time. By burying this rough estimate deep enough in the tree, you wind up with a pretty reasonable model. However, this produces an incomplete policy, which means that it is more useful for a replanning agent than for a standard planning agent. Minimax replanning is the usual approach for complex games (it is, if I'm not mistaken, the basic algorithm followed by Deep Blue), but since this is a very simple game you probably don't need to take this approach.
A side note on abstraction
Note that all of these solutions are conceptualized as either numeric changes to or estimations of the utility function. This is, in general, preferable to arbitrarily throwing away possible policies. After all, that's what your utility function is for -- any time you make a policy decision on the basis of anything except the numeric value of your utility, you are breaking your abstraction and making your code less robust.
I have 8 different arrays, and each array has 8 characters in it,
std::string str_v1 = v1.to_string();
char arr_v1[9] = {0};
std::copy(str_v1.begin(), str_v1.end(), arr_v1); // from str_v1 to str_v8
std::string str_v8 = v8.to_string();
char arr_v8[9] = {0};
std::copy(str_v8.begin(), str_v8.end(), arr_v8);
how to convert this into 8x8 matrix? I want to put these values column by column, like, each array is converted to one column of the matrix, like array1 to column1, array2 to column2, and so on, like array1 values will be placed like matrix[0][0], matrix[1][0], matrix[2][0] and so on..
I think, something like this needs to be done:
char matrix[8][8];
for( int y=0;y<8;y++)
{
matrix[y][0] = arr_v1[y];
matrix[y][1] = arr_v2[y];
matrix[y][2] = arr_v3[y];
matrix[y][3] = arr_v4[y];
matrix[y][4] = arr_v5[y];
matrix[y][5] = arr_v6[y];
matrix[y][6] = arr_v7[y];
matrix[y][7] = arr_v8[y];
}
for( int y=0;y<8;y++)
{
for( int z=0;z<8;z++)
{
switch(y)
{
case 0:
matrix[z][y] = arr_v1[z]; //Be pretty sure, possibly you are better than you believe
break; // I've placed y before z as y is the outer loop, hence it
case 1: // should be responsible for ROWS and z for COLUMNS
matrix[z][y] = arr_v2[z]; // Goes in matrix[0][1],[1][1],[2][1],[3][1]...[7][1]
break;
case 2:
matrix[z][y] = arr_v3[z]; // Goes in matrix[0][2],[1][2],[2][2],[3][2]...[7][2]
break;
case 3:
matrix[z][y] = arr_v4[z]; // Goes on
break;
case 4:
matrix[z][y] = arr_v5[z]; // And on
break;
case 5:
matrix[z][y] = arr_v6[z]; // And on
break;
case 6:
matrix[z][y] = arr_v7[z];
break;
case 7:
matrix[z][y] = arr_v8[z];
break;
}
} // Finally all 8 1x8 arrays stored into single 8x8 matrix
}
There you have it then your ways,each 1x8 coming as a COLUMN instead of a row as in previous one :)
char *matrix[9];
for (int i = 0; i < 9; ++i) {
matrix[i] = new char[9];
std::copy(your_ith_string.begin(), your_ith_string.end(), matrix[i]);
}
//Finish your work with the matrix
for (int i = 0; i < 9; ++i) {
delete[] matrix[i];
}
You yourself were quite correct :
for( int y=0;y<8;y++)
{
for( int z=0;z<8;z++)
{
switch(y)
{
case 0:
matrix[y][z] = arr_v1[z]; //Be pretty sure, possibly you are better than you believe
break; // I've placed y before z as y is the outer loop, hence it
case 1: // should be responsible for ROWS and z for COLUMNS
matrix[y][z] = arr_v2[z]; // Goes in matrix[1][0],[1][1],[1][2],[1][3]...[1][7]
break;
case 2:
matrix[y][z] = arr_v3[z]; // Goes in matrix[2][0],[2][1],[2][2],[2][3]...[2][7]
break;
case 3:
matrix[y][z] = arr_v4[z]; // Goes on
break;
case 4:
matrix[y][z] = arr_v5[z]; // And on
break;
case 5:
matrix[y][z] = arr_v6[z]; // And on
break;
case 6:
matrix[y][z] = arr_v7[z];
break;
case 7:
matrix[y][z] = arr_v8[z];
break;
}
} // Finally all 8 1x8 arrays stored into single 8x8 matrix
}
Hope this helps, if it doesn't just let me know, I'd be happy to help.
char matrix[8][8];
char *arr[8] = {arr_v1, arr_v2, arr_v3, arr_v4, arr_v5, arr_v6, arr_v7, arr_v8};
for( int y=0;y<8;y++) {
for (int i = 0; i < 8; ++i) {
matrix[y][i] = arr[i][y];
}
}