How to have a turn by turn management in C? - c

I want to make a game; say there are 50 turns and up to 4 players.
How should the code manage the turn by turn?
For 2 player I think it is that:
if (nbr_gamers == 2)
{
if ((turn % 2) == 0)
player = 1;
else
player = 0;
}
where the turn is the position of turn.
Is that about right?

Try this :
player = turn % nbr_gamers;

Related

Declaring a winner in a coin toss game

So, I'm running into an issue with the end of this program. It is supposed to award ten points for each correctly guessed coin flip, and at the end of the 100 tosses, a percentage of correct answers for each player as well as a total score, and finally it is to declare a winner. I seem to have the percentage correct, but the output for total score is jibberish, and I don't know how to get the program to use the results to declare a winner. Help?
#include "stdafx.h"
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int flip();
int main(void)
{
int player, side, toss, turn = 1, heads = 0, tails = 0;
int Play, wrong1, right1, wrong2, right2, r = (rand() % 2);
puts("Oh boy. My favorite game. Flip the coin. How super exciting. I apparently am little more than a childs plaything... \nEven though I am a program and thus do not have thumbs, hands, feet, skin or even a body, I will (reluctanly) play your silly little game, and 'flip a coin' 100 times.\nI hope you know, there are a lot better things I could be doing right now...\nReal quick, here's a list of things I could be doing right now.\n--Advance scientific research on globular clusters in the Milky Way Galaxy\n---Find the cure for cancer\n----Calculate the rate of deforestation in the Amazon\n-----Create the next generation of low emmission motor vehicles to lower the amount of CO2 in the atmosphere.\nBut, no. Let's play 'Flip the coin'. I couldn't possibly be more ecstatic, than if I woke this morning to see that I was on fire. While stapled to a wall. In New Jersey. With Kim Kardashian holding the fire extinguisher that is actually a can of hairspray... Yeah.\n");
puts("Are you player 1 or player 2?\n");//question to prompt user response
scanf_s("%d", &player);//how many players input
puts("\nSo, let's flip a coin, because apparently this game is the 'bees-nees' of the tech world... Enter 1 for heads, or 0 for tails.");
srand((unsigned)time(NULL));// seed random function with current time
for (toss = 1; toss <= 100; toss++)
{ //number of runs/tosses
if ( player=1)
if (turn == 1) // start of 2 player gaming
printf("\nPlayer 1, flip the coin. Player 2, take a guess.\n");// player 1 flip
else
printf("\nPlayer 2, it's your turn to flip the coin, Player 1 guess heads or tails.\n"); // player 2 flip
if (turn == 1)
Play = 1, turn = 0;
else
Play = 2, turn = 1;
printf("\nPlayer 1 toss the coin and guess the side\n");
int flipped;
scanf_s("\n %d", &side);// coin guess function
printf("\nThe coin came up %d\n", flip());
if (side == flip() && Play == 1)
right1++;
else
wrong1++;
if (side == flip() && Play == 2)
right2--;
else
wrong2++;
if (flip() == 1)
heads++;
else
tails++;
}
printf("heads was flipped %d times\n", heads);
printf("tails was flipped %d times\n", tails);
printf("Player 1 score %d \n", (right1 * 10) - (wrong1 * 5));// not working quite right player 1 eqation 1 //functions on the next 4 lines for score and confidence
printf("Player 1 confidence %d %'\n", (right1 * 2));//percent confidence player 1 Equation 2
printf("Player 2 score %d \n", (right2 * 10) - (wrong2 * 5));// not working quite right player 2 eqation 1
printf("Player 2 confidence %d %'\n", (right1 * 2));//percent confidence player 2 Equation 2
return 0;
}
int flip()// Coin flip function
{
int i = rand() % 2;
if (i == 0)
return 0;
else
return 1;
}
I strongly suggest properly formatting nested if statements with brackets and indentation.
if ( player=1)
if (turn == 1) // start of 2 player gaming
printf("\nPlayer 1, flip the coin. Player 2, take a guess.\n");// player 1 flip
else
printf("\nPlayer 2, it's your turn to flip the coin, Player 1 guess heads or tails.\n"); // player 2 flip
is much more difficult to read than
if ( player=1) {
if (turn == 1) { // start of 2 player gaming
printf("\nPlayer 1, flip the coin. Player 2, take a guess.\n");// player 1 flip
} else {
printf("\nPlayer 2, it's your turn to flip the coin, Player 1 guess heads or tails.\n"); // player 2 flip
}
}
And yes, as mentioned in the comments
if ( player=1) {
should be
if (player == 1) {
And
if (turn == 1)
Play = 1, turn = 0;
else
Play = 2, turn = 1;
should be
if (turn == 1) {
Play = 1;
turn = 0;
} else {
Play = 2;
turn = 1;
}
And you are also using right1, wrong1, right2, and wrong2 without initializing them.
And finally, in printf(), %' should be %% if you are trying to print a percent sign.

Function that returns structure giving bad return values

This is my first post so don't go rough on me if I happened to skip something I should have mentioned.
I am working on a program that simulates a tennis championship, and the outcome of an individual match via a rand() function to distribute the points among the 2 players currently in said match.
I have scanned the program and did my best to fix the issues but there is still a problem I can not fix, it is the function that determines the outcome of the matches. The problem is that the function returns strange values, nothing they should look like.
I first thought there is a problem with the declaration of the variables and the way I did operations with them but that did not seem to be the case, so I ran out of ideas and come to you.
Here is the code:
jucatori meci(jucatori jucator1,jucatori jucator2 )
{
int u =0; //scor jucator 1
int o=0; //scor jucator 2
int p; //aux j1
int l; //aux j2
int i;
do
{
//first loop, where player 1 serves
p= rand() % jucator1.sansaServire; //generate a number for player1
l= rand() % jucator2.sansaPrimire; //generate a number for player2
if(l>p)
{
o=o+1;
do
{
//going into the second loop, in this loop, here, player 2 serves
p = rand() % jucator1.sansaPrimire;
l = rand() % jucator2.sansaServire;
if(p>l) u = u+1;
if(l>p) o = o+1;
else break; //iese din bucla 2, juc1 va servi iarasi
}while(l>p);
}
else if(p>l) u = u+1;
}while(u + o < 51); //inchidem prima bucla
if(u > o && u - o > 10)
{
jucator1.meciurijucate++;
jucator2.descalificat = 1;
jucator1.scor1 = u;
jucator1.scor2 = o;
return jucator1;
} //return player 2, add 1 to the number of matches played and mark player 1 as out of the game
else if(o > u && o - u > 10)
{
jucator2.meciurijucate++;
jucator1.descalificat = 1;
jucator2.scor1 = o;
jucator2.scor1 = u;
return jucator2;
}//return player 1, add 1 to the number of matches played and mark player 2 as out of the game
else return meci(jucator1,jucator2); //call function again if the match is a draw
}
I will provide the full program if needed, just thinking that it would be pretty bulky to post the whole thing.

Tic Tac Toe, playing with PC (random)

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.

Battleship: place ships [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I wrote a battleship game on AVR device. Everything works just fine, only placing ships on game map causes little problems. Sometimes ships are placed next to each others even if I thought my code would prevent that. Have tried to debug it now for two days. Thought to just place the code of the place_ships -function here if someone of you could notice where I'm wrong with it.
int data_map[10][10]; //This has the data of where ships are, where player has shot etc.
char game_map[10][10]; //This is printed in UI. O for miss, X for hit.
int ship_sizes[] = {0,1,2,3,3,4,5};
int ships[] = {0,1,2,3,4,5,6};
void place_ships() { //Places the ships in the game map.
int other_ships; //Variabel for counting if there are already other ships in the area where trying place the ship.
for (i=6; i>0; i--) {
while (1) {
other_ships = 0; //Initialize.
ship_direction = rand() % 10; //Get random ship direction (1-4 = horizontal, 6-10 = vertical)
top_x = (rand() % 8) + 1; //Get random x-coordinate, not from map edges
top_y = (rand() % 8) + 1; //Get random y-coordinate, not from map edges
if (ship_direction < 5) {
if ((top_x-ship_sizes[i]) > -2) { //Make sure that ship has room in game map.
for (j=(top_y-1); j<(top_y+2); j++) { //Following 2 for-loops and if-statement inside makes sure that no other ships are in
//the area where the ship is tried to place.
for (k=(top_x+1); k>(top_x-(ship_sizes[i]-2)); k--) {
if ((data_map[j][k] == 1) || (data_map[j][k] == 2) || (data_map[j][k] == 3) || (data_map[j][k] == 4) || (data_map[j][k] == 5) || (data_map[j][k] == 6)) {
other_ships = 1; //Following 2 'breaks' and 'continue' are there for the situation if
break; //there are other ships in the area, stop placing ship and get new random coordinate and try again.
}
}
if (other_ships == 1) {
break;
}
}
if (other_ships == 1) {
continue;
}
for (l=top_x; l>(top_x-ship_sizes[i]); l--) {
data_map[top_y][l] = ships[i]; //If no other ships in the area, place the ship.
}
loading(); //Wait to optimize harware working. There are known timing issues on AVR. And this
//is here to try to avoid them.
break;
}
}
else if (ship_direction > 5) {
if ((top_y-ship_sizes[i]) > -2) { //Make sure that ship has room in game map.
for (j=(top_y+1); j>(top_y-(ship_sizes[i]-2)); j--) { //Following 2 for-loops and if-statement inside makes sure that no other ships are in
//the area where the ship is tryied toplace.
for (k=(top_x-1); k<(top_x+2); k++) {
if ((data_map[j][k] == 1) || (data_map[j][k] == 2) || (data_map[j][k] == 3) || (data_map[j][k] == 4) || (data_map[j][k] == 5) || (data_map[j][k] == 6)) {
other_ships = 1; //Following 2 'breaks' and 'continue' are there for the situation if
break; //there are other ships in the area, stop placing ship and get new random coordinate and try again.
}
}
if (other_ships == 1) {
break;
}
}
if (other_ships == 1) {
continue;
}
for (l=top_y; l>((top_y-(ship_sizes[i]))); l--) {
data_map[l][top_x] = ships[i]; //If no other ships in the area, place the ship.
}
loading(); //Wait to optimize harware working. There are known timing issues on AVR. And this
//is here to try to avoid them.
break;
}
}
}
}
}
Now the original problem is solved. Still some ships aren't placed. What ships function skips, varies.
In the last variant:
for (k=(top_x+1); k>(top_x-(ship_sizes[i]-2)); k--) {
I think the condition should be:
k > ( top_x - (ship_sizes[i] + 2) ) // not -2 but + 2
because as I suppose you want to check that the ship will not overlap all the length of the ship_sizes[i] and adjacent ones. The same is for y:
top_y-(ship_sizes[i] + 2) // or top_y - ship_sizes[i] - 2
I recommend you to extract this code to the function, such as CheckOverlap, because it will simplify the code reading and debugging.
Also, move up the valuation of the condition from the loop:
int length = top_x - (ship_sizes[i] + 2);
for (k= top_x+1; k > length; k--) {
Clearer code will also be:
int IsPlaced (j,k) {
return 1 <= data_map[j][k] && data_map[j][k] <=6;
}
In general, try to avoid code duplication, placing all doubling to functions. It will reduce the doubling errors and strongly simplify the design of your program, what is good for you and for all other readers.
The tests you're doing on data_map to find other ships are reading past the end of the array. You should clean up those loop conditions. For example, top_x can be as high as 8 after being assigned (rand() % 8) + 1. Then ship_sizes[i] can be as high as 5. So top_x+(ship_sizes[i]+2) can be 15.
I'm not sure fixing that will solve your problem, though, but it's a problem of its own.
You will find that the problem is in array indexing. Arrays in C are 0-indexed, and in several places you treat them as if they're 1-indexed.

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 */

Resources