This question already has answers here:
Why is my power operator (^) not working?
(11 answers)
Closed 2 years ago.
I found this code of a tic tac toe game in c++, but got confused with the side^1 in GetComputerMove function-->randMove = GetWinningMove(board, side ^ 1);
If anything raise to the power of one will only be the value itself, why should it be ^1? Cos it gave me an error when I remove ^1 :D
Can anyone help me to explain this? Thanks!
enum { NOUGHTS, CROSSES, BORDER, EMPTY };
enum { HUMANWIN, COMPWIN, DRAW };
const int directions[4] = { 1, 7, 6, 8 };
const int ConvertTo49[25] =
{
8, 9, 10,11,12,
15,16,17,18,19,
22,23,24,25,26,
29,30,31,32,33,
36,37,38,39,40
};
int GetWinningMove(int* board, const int side)
{
int ourMove = -1;
int winFound = 0;
int index = 0;
for (index = 0; index < 25; ++index)
{
if (board[ConvertTo49[index]] == EMPTY)
{
ourMove = ConvertTo49[index];
board[ourMove] = side;
if (FindFourInARow(board, ourMove, side) == 4)
{
winFound = 1;
}
board[ourMove] = EMPTY;
if (winFound == 1)
{
return ourMove;
}
ourMove = -1;
};
}
return ourMove;
}
int GetComputerMove(int* board, const int side)
{
int index;
int numFree = 0;
int availableMoves[25];
int randMove = 0;
//Set random number to randomly run a function
int randFunction = 0;
randFunction = (rand() % 2);
//Go for the winning move
randMove = GetWinningMove(board, side);
if (randMove != -1)
{
return randMove;
}
//If random function is 1, stop any winning move from the human
if (randFunction == 1)
{
randMove = GetWinningMove(board, side ^ 1);
if (randMove != -1)
{
return randMove;
}
}
randMove = 0;
//Loop through all squares and put piece in random place
for (index = 0; index < 25; ++index)
{
if (board[ConvertTo49[index]] == EMPTY)
{
availableMoves[numFree++] = ConvertTo49[index];
};
}
randMove = (rand() % numFree);
return availableMoves[randMove];
}
In C++, the ^ operator does not mean exponentiation (or raising to a given power); in fact, there is no exponentiation operator in C++ (you have to use the pow function to do that).
Rather, ^ is the exclusive or operator. In your case, given that side will have a value of either 0 or 1 (representing the machine or the player), the side ^ 1 expression will evaluate to the other value. That is, if side is 1, it will give 0 and, if side is 0, it will give 1.
Related
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 months ago.
Improve this question
#include <iostream>
int binary_search(int arr[], int size, int target)
{
int first = 0;
int last = size - 1;
int midpoint = (last + first) / 2;
while(first <= last)
{
if(arr[midpoint] == target)
{
return midpoint;
}
else if(arr[midpoint] < target)
{
first = midpoint + 1;
}
else if(arr[midpoint] > target)
{
last = midpoint - 1;
}
}
return 0;
}
int main()
{
int arr[] = {4, 12, 23, 43, 50, 60, 230, 290};
int size = sizeof(arr)/sizeof(arr[0]);
int target = 12;
std::cout << binary_search(arr, size, target);
}
if the midpoint value is lesser than the target it increases 'first' and if it's greater than the target it instead decreases 'last'. This continues until 'first' is equal to 'last'.
I saw another program where they called the function recursively but i wanted to make it work without it, what exactly am i doing wrong?
You basically forgot to update midpoint in each iteration.
An updated version of your code here (not using those "C" style arrays).It was also not clear if you meant to return the found value or the index at which it was found.
#include <iostream>
#include <vector>
auto binary_search(const std::vector<int>& values, int value)
{
std::size_t first = 0;
std::size_t last = values.size() - 1; // use vector it keeps track of its size
while (first <= last)
{
std::size_t midpoint = (last + first) / 2; // you forgot to update midpoint each loop
if (values[midpoint] == value)
{
return values[midpoint]; // <== do you want to return the position or the value?
}
if (values[midpoint] < value)
{
first = midpoint + 1;
}
else if (values[midpoint] > value)
{
last = midpoint - 1;
}
}
return 0;
}
int main()
{
std::vector<int> values{ 4, 12, 23, 43, 50, 60, 230, 290 };
std::cout << binary_search(values, 12);
return 0;
}
You always access the same value of the array arr[midpoint]
while(first <= last)
{
if(arr[midpoint] == target)
{
return midpoint;
}
else if(arr[midpoint] < target)
{
first = midpoint + 1;
}
else if(arr[midpoint] > target)
{
last = midpoint - 1;
}
}
Because you never update the value of midpoint so the conditions of your if statements will always give the same result
you wrote mid = (high+low)/2 outside while loop
If your sequence is 4 2 1, the largest jump is from 4 to 2. If your sequence is 3 10 5 16 8 4 2 1, the largest jump is from 5 to 16.
I've made an algorithm however I'm not completely sure what I have done wrong (whever I haven't made the loop properly, set my variables correctly, or something else). I'm not sure what I need to set my index, BiggestDiff, or CurrentDiff too. I tried using a while loop to compare each number in my vector but I get zero (I'm assuming because I set BiggestDiff to zero)
If anyone can point me in the right direction, show me an example, or something else, that will be greatly appreciated.
Here is my code below
int findBiggestDiff(std::vector<int> sequence)
{
int index = 0;
int BiggestDiff = 0 ;
int CurrentDiff = BiggestDiff;
CurrentDiff = std::abs(sequence[index] - sequence[index + 1]);
while (index < sequence.size())
{
if (CurrentDiff > BiggestDiff)
{
BiggestDiff = CurrentDiff;
}
return index;
}
}
Try this:
{
int indexOfBiggestJump = 0;
int BiggestDiff = 0 ;
int CurrentDiff = BiggestDiff;
for(int i = 0; i < sequence.size() - 1; i++) {
CurrentDiff = std::abs(sequence[i] - sequence[i + 1]);
if (CurrentDiff > BiggestDiff)
{
BiggestDiff = CurrentDiff;
indexOfBiggestJump = i;
}
}
return indexOfBiggestJump;
}
There are several errors in your code.
your return index literally does nothing, only returns index (which will be 0) always.
you are not saving the index of the biggest jump anywhere.
if you are looking positions i and i + 1, you must go until sequence.size() - 1, otherwise you will look out of the bounds of sequence.
You aren't recalculating CurrentDiff at all. Also, your return statement in the in the wrong spot. You can do something like this (not tested)
int findLargest( const std::vector<int> &sequence ) {
if ( sequence.size() < 2 ) return -1; // if there's not at least two elements, there's nothing valid.
int index = 0;
int biggestIndex = -1;
int biggestDiff = -1;
while (index < sequence.size() - 1) // -1 so that the +1 below doesn't go out of range
{
// get the current difference
int currentDiff = std::abs(sequence[index] - sequence[index + 1]);
if (currentDiff > biggestDiff)
{
// update stats
biggestIndex = index;
biggestDiff = currentDiff;
}
++index;
}
return biggestIndex
}
int main() {
//…
int index = findLargest( sequence );
if ( index != -1 ) {
std::cout << "Biggest difference was between " << sequence[index] << " and " << sequence[index+1];
}
}
I have a minimax tree and an evaluation function.The minimax function return only an integer(best value).How can i store the first move of the way of the founded best value ?
here's my code :
int Brain::MiniMax(GameBoard gb, int depth,int Turn,int lastcount) //0->Max 1->Min
{
if (depth == 5)
return Evaluation(lastcount, gb);
int bestval = 0;
if (Turn == 0)
{
bestval = -100;
vector<pair<int, pair<int, int>>> possibleFences = this->PossibleFences(gb);
for (int i = 0; i < possibleFences.size(); i++)//ForFences
{
int cnt = 0;
NextShortestPathMove(cnt, gb.OpponentPawn,gb);
if (gb.CanPutFence(possibleFences[i].first, possibleFences[i].second.first, possibleFences[i].second.second) == 0)
continue;
gb.PutFence(possibleFences[i].second.first, possibleFences[i].second.second, possibleFences[i].first);
int value = MiniMax(gb, depth + 1,1, cnt);
if (value > bestval)
{
bestval = value;
move = possibleFences[i];
}
}
return bestval;
}
else if (Turn == 1)
{
bestval = +100;
int** possibleMoves = this->PossibleMoves(gb.OpponentPawn.Row, gb.OpponentPawn.Column, gb.OpponentPawn,gb);
for (int i = 0; i < 6; i++)
{
if (possibleMoves[i][0] == -1)
continue;
int cnt = 0;
NextShortestPathMove(cnt, gb.OpponentPawn,gb);
gb.MoveOpponentPlayer(possibleMoves[i][0], possibleMoves[i][1]);
int value = MiniMax(gb, depth + 1, 0,cnt);
bestval = min(value, bestval);
}
return bestval;
}
}
for example at the end if the bestval = 10, i want the first move of the selection of this bestval. now i store the move in the 'move' variable but it doesn't work correctly.
In a practical minimax algorithm implementation, a hash table is used to enter evaluated scores and moves including hashkey, a value unique for each position of the players and pieces. This is also useful during implementation of "force move".
During move evaluation, hashkey, score and move position are recorded in a struct and the hash table as well. So, after successful search, the entire struct is returned to enable update of the graphics and game status.
A typical hash entry looks like so:
struct HashEntry {
int move;
int score;
int depth;
uint64_t posKey;
int flags;
};
I'm trying to implement NegaMax ai for Connect 4. The algorithm works well some of the time, and the ai can win. However, sometimes it completely fails to block opponent 3 in a rows, or doesn't take a winning shot when it has three in a row.
The evaluation function iterates through the grid (horizontally, vertically, diagonally up, diagonally down), and takes every set of four squares. It then checks within each of these sets and evaluates based on this.
I've based the function on the evaluation code provided here: http://blogs.skicelab.com/maurizio/connect-four.html
My function is as follows:
//All sets of four tiles are evaluated before this
//and values for the following variables are set.
if (redFoursInARow != 0)
{
redScore = INT_MAX;
}
else
{
redScore = (redThreesInARow * threeWeight) + (redTwosInARow * twoWeight);
}
int yellowScore = 0;
if (yellowFoursInARow != 0)
{
yellowScore = INT_MAX;
}
else
{
yellowScore = (yellowThreesInARow * threeWeight) + (yellowTwosInARow * twoWeight);
}
int finalScore = yellowScore - redScore;
return turn ? finalScore : -finalScore; //If this is an ai turn, return finalScore. Else return -finalScore.
My negamax function looks like this:
inline int NegaMax(char g[6][7], int depth, int &bestMove, int row, int col, bool aiTurn)
{
{
char c = CheckForWinner(g);
if ('E' != c || 0 == depth)
{
return EvaluatePosition(g, aiTurn);
}
}
int bestScore = INT_MIN;
for (int i = 0; i < 7; ++i)
{
if (CanMakeMove(g, i)) //If column i is not full...
{
{
//...then make a move in that column.
//Grid is a 2d char array.
//'E' = empty tile, 'Y' = yellow, 'R' = red.
char newPos[6][7];
memcpy(newPos, g, sizeof(char) * 6 * 7);
int newRow = GetNextEmptyInCol(g, i);
if (aiTurn)
{
UpdateGrid(newPos, i, 'Y');
}
else
{
UpdateGrid(newPos, i, 'R');
}
int newScore = 0; int newMove = 0;
newScore = NegaMax(newPos, depth - 1, newMove, newRow, i, !aiTurn);
newScore = -newScore;
if (newScore > bestScore)
{
bestMove = i;
bestScore = newScore;
}
}
}
}
return bestScore;
}
I'm aware that connect four has been solved are that there are definitely better ways to go about this, but any help or suggestions with fixing/improving this will be greatly appreciated. Thanks!
Actually i am trying to solve SPOJ Problem:
[SPOJ] http://www.spoj.com/problems/SQRBR/ . I came up with recurence to solve it but i am not getting how to do memoisation. Any suggestion on how to memoisation for given problem will be helpful. my code is giving correct answer , but it is giving TLE in spoj Here my code :
#include <iostream>
#include <cstdio>
using namespace std;
void balancedParen(int n, int open, int position, int close, char str[], string s, long long int &counter) {
if(close == n) {
str[pos] = '\0';
printf("%s\n", str);
counter++;
return;
}
if(s[position] == '(' ) {
if(open <= n-1) {
str[position] = '(';
balancedParen(n, open+1, position+1, close, str, s, counter);
}
} else {
if(open < n) {
str[position] = '(';
balancedParen(n, open+1, position+1, close, str, s, counter);
}
if(open > close) {
str[position] = ')';
balancedParen(n, open, position+1, close+1, str, s, counter);
}
}
return ;
}
int main() {
int a[100], n, k, i;
long long counter = 0;
int testCases;
scanf("%d", &testCases);
while(testCases--) {
scanf("%d", &n);
scanf("%d", &k);
char str[100];
string s = "..........................................................................";
for(i = 0; i < k; i++) {
scanf("%d", &a[i]);
s[a[i]-1] = '(';
}
balancedParen(n, 0, 0, 0, str, s, counter);
printf("%lld\n", counter);
counter = 0;
}
return 0;
}
I can think of one relatively simple and possibly significant optimization.
First, instead of making the "counter" a reference, make it the return value of the function. Hear me out for a bit here.
Now say the positions you're given are "1, 7, 15". Instead of recursively going "1, 2, 3, 4, 5, 6, 7", you can be a little tricky and go to 7 in one step.
You just need to count the number of permutations which can be used to go between 1 and 7, for every possible number of opening parens (in this case, 3, 4, 5 and 6)
For example, how many ways exist to have 3 opening parens between 1 and 7?
[[[]]]
[[][]]
[][][]
[[]][]
[][[]]
5 permutations (unless I missed one). So you can add 5*balancedParen(n, open+3, position+6, close+3, str, s, counter) to your result. And do a similar thing for 4, 5, and 6 opening parens.
Of course you'd need to write another function (recursive approach seems simplest) to find that number "5". But the advantage is that the total number of function calls is now (calls to get from 1 to 7) + (calls to get from 7 to 15), rather than (calls to get from 1 to 7) * (calls to get from 7 to 15).
Here is some code which should work using the algorithm I described:
int countPermutations(int unclosed, int length, int toOpen)
{
if (toOpen > length) // impossible to open this many, not enough length
return 0;
int toClose = length-toOpen;
if (toClose - toOpen > unclosed)
return 0; // No possibilities; not enough open parens to fill the length
if (toOpen == 0 || toOpen == length)
return 1; // Only one possibility now
int ret = 0;
if (toOpen > 0) // Count permutations if we opened a paren here
ret += countPermutations(unclosed+1, length-1, toOpen-1);
if (unclosed > 0) // Count permutations if we closed a paren here
ret += countPermutations(unclosed-1, length-1, toOpen);
return ret;
}
int countNLengthSolutions(int n, int unclosed, int position, int *positions, int remainingPositions)
{
if (n % 2 != 0)
return 0; // must be a length divisible by 2
if (position > n)
return 0;
if (n-position < unclosed)
return 0; // too many open parens, no way to complete within length
if (remainingPositions == 0)
{
// Too many open parens to close by the time we get to length N?
if ((n - position) < unclosed)
return 0;
else // Say we have 4 open and a length of 10 to fill; we want (10-4)/2 = 3 more open parens.
return countPermutations(unclosed, n-position, (n-position - unclosed)/2);
}
else
{
int ret = 0;
int toFill = *positions - position - 1;
for (int openParens = 0; openParens <= toFill; openParens++)
{
int permutations = countPermutations(unclosed, toFill, openParens);
if (permutations > 0)
ret += permutations*countNLengthSolutions(n, unclosed+(2*openParens-toFill)+1, position+toFill+1, positions+1, remainingPositions-1);
}
return ret;
}
}
I may have a bug somewhere, I didn't really spend the time to check, but I verified it works for all the sample input.