Tic Tac Toe, playing with PC (random) - c

if (turn == tick) {
/*first player*/
Form1->Label1->Caption = "X pyr";
fields[row][kol] = 1;
Form1->BitBtn1->Glyph->LoadFromFile("tick.bmp");
turn = tack;
}
else {
do {
//random
row = rand() % 3;
kol = rand() % 3;
}
while (fields[row][kol] == 0);
/*cpu*/
Form1->Label1->Caption = "CPU";
fields[row][kol] = 2;
Form1->BitBtn1->Glyph->LoadFromFile("tack.bmp");
turn = tick;
}
}
The main problem is that when I make my move, computer just clicks on first element and after every next move it does the same.
Computer just uses first TicTacToe game board square.

If i understand correctly the fields variable contain the board with 0 for unoccupied cell, 1 for human player, 2 for CPU.
In this case the terminal condition of the while is wrong while (fields[row][kol] == 0);, you must loop when the cell is occupied (trying to search for free cells).
do {
//random
row = rand() % 3;
kol = rand() % 3;
}
while (fields[row][kol] != 0);
Note: you are initializing all elements of fields to 0, that don't appear in the code.

CPU player loops until it finds a row and col value which is not equal to 0. do-while loop below loops if fields[row][col] is equal to 0 meaning after the exit fields[row][col] will be different than 0.
do {
...
} while(fields[row][col] == 0)
// fields[row][col] is different than 0 here
In your case field value not equal to 0 means a square already used by human or computer, so computer does the same move every time.

Related

C program stops on certain number [duplicate]

This question already has answers here:
Project Euler Question 14 (Collatz Problem)
(8 answers)
Closed 1 year ago.
Hi I am new to C and I chose a project to get better
I wanted to make a program that would brute force every number if it is according to Collatz conjecture.
Collatz conjecture:
For those who do not know what Collatz conjecture is click here
Summary:
If a number is odd it is multiplied by 3 and increased by 1
If even it is divided by 2
This is repeated until it reaches 1
My code:
#include <stdio.h>
int main(){
int n, x, a, b;
n = 5; //number we check first (has to be bigger than 4 because 4,3,2,1 is a loop)
//n is later on a number that is currently being tested
//all numbers smaller than 2 ** 64 were brute force tested and are according to Collatz's conjecture
x = n; //x begins as n and then changes according to rules of cenjecture until it reaches 1
a = 1; //a is set to 1 until x = 1 which means that number n is according to conjecture
b = 1; //creates an infinite loop
while(b == 1){ //runs forever
if(a == 1){
if(x == 1){
a = 0; //if x reaches 1 (number n is according to conjecture) a is set to 0 and n is increased by 1 ===
} // ||
else{ // ||
if(x % 2 == 0){ // ||
x = x / 2; // ||
} // ||
else{ // ||
x = x * 3 + 1; // ||
} // ||
} // ||
} // ||
else{ // ||
printf("%d \n", n); // ||
n = n + 1; // <<<<<============================================================================
x = n; //
a = 1; //
}
}
}
Problem:
The problem is that when I run it it stops on number 113383 and has problems with it. I even let it run for more than 5 minutes but it did not do anything. I even tried to run the same number in my python program which test input number and it had it in no time.
I tried to start with n = 113384 and it worked and stopped again on 134378.
Is number 113383 anyhow different in C or is there a flaw in my code.
Please help if you can.
Thank you very much
Try declaring the variable as a "long int" this could be due to the maximum size of an int witch is –32,767 to 32,767

Fast image smoothing in C

Problem: Given a square matrix, A, whose dimension, N, is a divisor of 64, find a fast way to smoothe A by letting a 3 x 3 grid slide over the A, s.t. for each entry A_{ij}, we replace this with the average of the 8 nearby neighbors.
My solution: Let's assume A is a 4x4 matrix, we initialize as:
int A[NxN] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
Which is equivalent to:
In the first iteration, we see A_ij is equivalent to 0, which is in the center of the 3x3 matrix. We realize that indices (0,0), (0,1), (0,2), (1,0), (1,3) of the 3x3 matrix is trying to find numbers not existing. Therefore, we see that the result must be that if $A_{ij}$ = 0, then we must replace it by $0+1+4+5 = \frac{10}{4}$.
Next iteration, we see A_ij is equivalent to 1, which is now the new center of the 3x3 matrix, and we see that the numbers to be included in the averaging is: 0,1,2,4,5,6.
So when we are in a corner of our matrix, A, we need 4 numbers for averaging, in the top of the matrix, we need 6 numbers, and if A_{ij} = 6, meaning in the middle of the matrix, we will need 9 numbers.
What I am trying to find is a general pattern for these sequences of needed numbers in order to do this in hopefully a single \texttt{for loop}.
I found that when i % dim == 0, we are in the left side of the matrix, when i % dim == 3 we are in the left side, but I have tried to find a general index pattern to define my averaging functions to pair with my if conditions.
#include <stdio.h>
int smooth(int dim);
int main() {
smooth(4);
}
int smooth(int dim) {
int A[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int K[dim*dim]; // Replacement array, otherwise we average averages
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j++)
{
// Corner cases
if ((i % dim == 0 && j % dim == 0) || (i % dim == dim - 1 && j % dim == 0) || (i % dim == 0 && j % dim == dim -1) || (i % dim == dim -1 && j % dim == dim-1))
{
// Average function on corners
}
// else if not corner and in "edge row", top/bottom {
// Average 6 numbers
}
}
}
return 0;
}
Your mre is a bit theoretical, I will leave all parts which are not practically plausible out of this. They obviously only serve to provide a MRE quick.
Interpret your input as 2D.
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
More abstractly as
0 ... ( 0*dim + (dim-1))
(1 * dim) ... ( 1*dim + (dim-1))
(2 * dim) ... ( 2*dim + (dim-1))
.
.
.
((dim-1) * dim) ... ((dim-1)*dim + (dim-1))
Here is the structure I propose for your function
int smooth(int dim)
{
int A[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; //obvious MRE weirdness, ignored
int K[dim*dim]; // Replacement array, otherwise we average averages
// Corner cases
K[0] = A[0]; /* dummy, to be calculated */
K[dim-1] = A[dim-1]; /* dummy, to be calculated */
K[dim*(dim-1)] = A[dim*(dim-1)]; /* dummy, to be calculated */
K[dim*dim-1] = A[dim*dim-1]; /* dummy, to be calculated */
for (int i = 0; i < dim-2; i++)
{
// edge cases
{
K[1+i] = A[1+i]; /* dummy, average to be calculated */
K[dim*(1+i)] = A[dim*(1+i)]; /* dummy, average to be calculated */
K[dim*(1+i)+dim-1] = A[dim*(1+i)+dim-1]; /* dummy, average to be calculated */
K[dim*(dim-1)+i+1] = A[dim*(dim-1)+i+1]; /* dummy, average to be calculated */
}
// center part
for (int j = 0; j < dim-2; j++)
{
K[(i+1)*dim+1+j] = A[(i+1)*dim+1+j]; /* dummy, average to be calculated */
}
}
return 0;
}
For all cases of A[...]; /* dummy, average to be calculated */ you can use the same index for reading from A as for writing into K and
subtract 1 to get to the pixel to the left
add one to get to the pixel to the right
add dim to get to the pixel below
subtract dim to get to the pixel above
do that for all neigbouring pixels you decide to use
sum the values up to determine the average
In all cases where you need a neighbour pixel you will always arrive at a valid pixel, because either there is one or you are not going to need it.
(Note: I strictly practice starting for loops from 0 and count up with <needed_length. There is an alternative to start from 1 and count up to needed length +1. It will in this case here make the index calculations read easier. This is a matter of habits. I come from an environment where you have to prepare strong reasoning for loops not starting at 0. Habits are hard to shed. Going through the alternative concept will probably provide you with some helpful learning opportunity.)

C - number sorting description

I have written a C program which sorts an array of 50 of random numbers from 0 - 255. The highest number once sorted is displayed on 8 LEDs as binary digits. The same for the lowest sorted number. I fully understand the program however I need to write up a brief description of it and am struggling with these two functions:
void binaryLowesttNumber()
{
int remainder = lowArray; /* remainder is what I am going to be left with after taking away the value of the pins,
sets remainder as the lowest sorted number */
int j = 128; // value of pins in binary
int i = 7; // index of current pin
while (i >= 0)
{
if (remainder >= j) //if remainder is larger or equal to the value of the current pin
{
digitalWrite(pinArray[i], HIGH);
remainder = remainder - j; // takes value of pin away from remainder
j = j >> 1; // halves the value of j
i--; // moves to next pin
}
else
{
j = j >> 1; // halves the value of j
i--; // moves to next pin
}
}
}
void binaryHighestNumber()
{
int remainder = highArray; // same as binaryLowestNumber function except the remainder will be the highest sorted number
int i = 128;
int thisPin = 7;
while (remainder > 0)
{
while (remainder >= i)
{
double j = i / 2;
digitalWrite(pinArray[thisPin], HIGH);
remainder = remainder - i;
i = i - j;
thisPin--;
}
while (remainder < i)
{
int j = i / 2;
if (j >= 1)
{
i = i - j;
thisPin--;
}
else
{
i = 0;
}
}
}
}
Concentrate on what the function does (not on how it does that, your code explains that). What does function binaryHighestNumber() do? As I understood you correctly, your function sorts an array of 50 of random numbers from 0 - 255 and displays the highest number on 8 LEDs as binary digit. So a perfectly good and informative comment would be:
/**
* Sort an array of 50 random numbers from 0 - 255 and
* display the highest number on 8 LEDs as binary digit using 'digitalWrite()' function.
*/
void binaryHighestNumber()
...
Try to use doxygen format to document your code, that way it will be easy understandable by others who had worked with doxygen. And document what the function does, not how it does that. See Linux kernel coding commenting or GNU coding standard.
EDIT:
I don't see any sorting done in binaryHighestNumber() function. Are you sure this function sorts the array? As I inspect the function definition, all it does is to display a value stored in variable highArray on LEDs. Maybe a better comment would be this:
/**
* Display the highest number obtained from sorting array of 50 elements
* stored in a global variable 'highArray'
* on 8 LEDs as binary digit using 'digitalWrite()' function.
*/
void binaryHighestNumber()
...
EDIT2:
The intent was, that the question is how the code works and now how to comment it, so here we go. Let's concentrate on binaryHighestNumber().
Basically what the function does, is that it sets gpios high which number corresponds to the bit number in highArray. So for a highArray = 0b10101010 we want to light up gpios numbers 7, 5, 3 and 1 (numbering from 0). For highArray = 0b10100101 we want to light up gpios numbers 7, 5, 2 and 0.
The code binaryHighestNumber() keeps track of a remainder - the number substracted from the number of gpios already examined. The other is i - a value that is equal to 2 to the power of currently checked gpio number. thisPin is used to track the gpio number we currently check and it is equal to log2(i).
At first remainder = highArray and i = 128 and we want to check, if we should set gpio number 7 to high. We need to check if bit number 7 in the remainder is set or not. If the remainder is greater then 128, that means that the bit number 7 is set, that means that gpio number 7 needs to be set to high. If bit number 7 is not set, that means that remainder is lower then 128, we don't light the gpio. If the bit number 7 was set, we remove bit 7 from remainder (ie. substract i, which is eqaul to 128, from the remainder) and then bitshift i to the right by dividing it by 2. If bit number 7 was not set, we only bitshift i to the right.
Now remainder = highArray&0b01111111 and i = 64. We continue the process. If the remainder is greater than 64, that means that bit number 6 is set and we need to set gpio number 6 high, remove bit 6 from the remainder (by substracting i from it) and bitshift i to the left (by diving it by 2). If the number is lower then 64, we only bitshift i and continue.
Then remainder = highArray&0b00111111 and i = 32 and we continue until the remainder is equal to zero. (ie. remainder = highArray&0b00000000.
You can simplify the code, to somewhat easier form, like this:
void binaryHighestNumber()
{
int remainder = highArray; // same as binaryLowestNumber function except the remainder will be the highest sorted number
int i = 128;
int thisPin = 7;
while (remainder > 0) {
if (remainder >= i) {
digitalWrite(pinArray[thisPin--], HIGH);
remainder -= i;
i -= i/2;
}
if (remainder < i) {
if (i != 1) {
i -= i/2;
thisPin--;
} else {
i = 0;
}
}
}
}
or maybe like this:
void binaryHighestNumber()
{
int remainder = highArray; // same as binaryLowestNumber function except the remainder will be the highest sorted number
int i = 128;
int thisPin = 7;
while (remainder > 0) {
if (i != 0 && remainder >= i) {
digitalWrite(pinArray[thisPin--], HIGH);
remainder -= i;
i /= 2;
}
if (remainder < i) {
i /= 2;
thisPin--;
}
}
}
Pay attention to that i -= i/2; is not equal to i /= 2;, when i = 1. Also i have removed while loops, they don't change anything. I have removed j variables, they are not needed and don't change anything.
There is a much simpler way to check each bit in a byte and light up these gpios, but I think i will leave that to you to find out.

While(1) works first four times that function is called, then becomes infinite. (C) [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have a tic tac toe board that I'm working on for fun and I've come across a problem. Basically I generate the two x,y coordinates randomly and then run them through a while loop. If the coordinate position hasn't been marked, then it marks the spot. Else it'll continue running and generate a new pair of coordinates. This seems to work for the first four times that the function is called, but then any subsequent uses of the function cause it to spiral out of control. Hoping someone might be able to point me in the right direction as well as tell me if logic is incorrect somewhere. Constructive criticism is great.
Thanks in advance and here's the code for the X's move function (the O has almost the same code):
void Xmove(struct config *cp) {
int ran1, ran2;
srand((unsigned) time(NULL));
ran1 = rand() % 3;
ran2 = rand() % 3;
if(cp->grid[1][1] == ' ') {
cp->grid[1][1] = 'X';
printGrid(cp);
return;
}
while(ran1 == 1 && ran2 == 1) {
ran1 = (rand() % 3);
ran2 = (rand() % 3);
}
int looper = 1;
while (looper) {
if(cp->grid[ran1][ran2] != 'O' && cp->grid[ran1][ran2] != 'X') {
cp->grid[ran1][ran2] = 'X';
printGrid(cp);
looper = 0;
}
ran1 = (rand() % 3);
ran2 = (rand() % 3);
}
}
Back to the the original question about your infinite loop and your code, You cannot make the loop break solely on the assumption of finding an empty slot and filling it. You should not be even entering the loop if there are no slots left available. In fact, you should not even call either Move() function at all if there are no open tiles to fill, and honestly that should be maintained as a decrement-counter of the config struct.
But that aside, detection of open-tiles-remaining could be done a number of ways. One is presented below that requires no other modifications to the config table, etc. This you can easily do by building a list of viable tiles, and choosing a single random entry from that. The following replaces everything past your initial check for the center slot being open.
// build a table of open tiles
int ar[9] = {0};
int n=0,i=0,j=0;
for (i=0;i<3;++i)
for (j=0;j<3;++j)
if (cp->grid[i][j] != 'O' && cp->grid[i][j] != 'X')
ar[n++] = i*3+j;
// now you have the list of available tiles
// in `ar[0..n-1]`. choose ONE via `rand()`
if (n > 0)
{
n = ar[rand()%n];
cp->grid[n/3][n%3] = 'X'; // or 'O'
}
I'd eliminate the random looping altogether, instead every time I needed to make a move I would generate a random permutation of the digits 0-9 inclusive, and use that to walk the board, looking for where to put an X or an O as needed. Something like this:
int randperm[9], i = 0;
/* fill the array randperm with the numbers 0 through 8 in
* order
*/
for(i = 0; i != 9; i++)
randperm[i] = i;
/* Now mix the numbers up, so that the array ends up in
* some "random" order: that is, generate a permutation
* of the digits 0-8.
*/
for(i = 8; i > 0; i--)
{
int j = rand() % (i+1);
int temp = randperm[j];
randperm[j] = randperm[i];
randperm[i] = temp;
}
/* Now try to find a spot. We will use our randperm array to
* determine which cell to look at. Remember that the array
* contains the numbers 0-8 in some random order.
*/
for(i = 0; i != 9; i++)
{
/* We split a number from 0-8 into two numbers (x and y),
* each from 0 to 2:
*
* 0 -> 0 0, 1 -> 1 0, 2 -> 2 0,
* 3 -> 0 1, 4 -> 1 1, 5 -> 2 1,
* 6 -> 0 2, 7 -> 1 2, 8 -> 2 2
*
* notice that (y * 3) + x = randperm[i]
*/
int x = randperm[i] % 3;
int y = randperm[i] / 3;
/* check if the spot at grid[x][y] is available, if it is
* take it and return.
*/
}
/* If we get here there's no spot to put an X or an O... board is full */

Having trouble with a Collatz Conjecture test in C

I am trying to create a code that will take the number 2 to 100, and test each for the collatz conjecture.
The goal is that for each number, if it is even, divide it by two, and if it is odd, then multiply it by 3 and add 1.
It prints each step, and each number should stop testing if it reaches 1. Why doesn't it work?
#include <stdio.h>
int main()
{
int number, position;
position == 2;
number == 2;
while (position <= 100)
{
while (number != 1)
{
if (number % 2 == 0)
{
number = number/2;
printf("%d\n", number);
}
else if (number % 2 != 0)
{
number = number*3;
number = number + 1;
printf("%d\n", number);
}
}
position = position + 1;
number = position;
}
}
It prints recurring Os
Fix the == vs =:
position = 2;
number = 2;
Also, the else if is unnecessary. The opposite of even is odd, so a plain else will suffice :-)
You have set position and number with a double equal == (Comparision Operator) instead of using single equal = (Assignment Operator) so that the algorithm is comparing them instead of assigning a value.
The assignment should look like this:
position = 2;
number = 2;
Also you can do it when you first define them:
int number=2, position=2;
Apart from that the code is correct, the only thing to highlight is that you don´t need to use else if because it can just be even or odd so a single else would be enough.
Hope I´ve helped :-)

Resources