I've written the following code for a tic-tac-toe game on my own:
#include <stdio.h>
#include <math.h>
void instructions();
void printboard(char board[3][3]);
int wincheck(char board[3][3]);
int main(){
char tictac[3][3] = {{'-', '-', '-'}, {'-', '-', '-'}, {'-', '-', '-'}};
int player = 0;
int win = 0;
int player_choice = 0;
int row = 0;
int col = 0;
instructions();
for(int i=0; i<9 && win==0; i++){
printboard(tictac);
player = i%2 + 1;
do{
printf("\nPlayer #%d, enter your spot choice:\n", player);
scanf("%d", &player_choice);
if(player_choice == 1){
row = 0;
col = 0;
}
else if(player_choice == 2){
row = 0;
col = 1;
}
else if(player_choice == 3){
row = 0;
col = 2;
}
else if(player_choice == 4){
row = 1;
col = 0;
}
else if(player_choice == 5){
row = 1;
col = 1;
}
else if(player_choice == 6){
row = 1;
col = 2;
}
else if(player_choice == 7){
row = 2;
col = 0;
}
else if(player_choice == 8){
row = 2;
col = 1;
}
else if(player_choice == 9){
row = 2;
col = 2;
}
else{
printf("Not a valid choice, please choose again.");
}
}while(player_choice<0 || player_choice>9 || tictac[row][col]!='-');
if(player == 1){
tictac[row][col] = 'X';
}
else if(player == 2){
tictac[row][col] = 'O';
}
if(wincheck(tictac)!=0){
win = player;
}
}
printboard(tictac);
if(!win){
printf("\n\nTHE GAME IS A DRAW!\n");
}
else{
printf("\n\nCONGRATULAIONS PLAYER #%d, YOU WON!\n", win);
}
}
void instructions(){
printf("\n\t\t\t WELCOME TO TIC TAC TOE!\n");
printf("\nGame Rules:\n");
printf("\nThe program will ask the player to enter which spot they would like to place their X or O.\nPlease use spot numbers as shown below:\n\n");
printf("\t\t\t\t 1 | 2 | 3 \n");
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t 4 | 5 | 6 \n");
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t 7 | 8 | 9 \n");
printf("\n\t------------------------LET'S BEGIN!------------------------\n\n\n");
}
void printboard(char board[3][3]){
printf("\t\t\t\t %c | %c | %c \n", board[0][0], board[0][1], board[0][2]);
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t %c | %c | %c \n", board[1][0], board[1][1], board[1][2]);
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t %c | %c | %c \n", board[2][0], board[2][1], board[2][2]);
}
int wincheck(char board[3][3]){
if((board[0][0]==board[0][1] && board[0][0]==board[0][2]) || (board[1][0]==board[1][1] && board[1][0]==board[1][2]) || (board[2][0]==board[2][1] && board[2][0]==board[2][2])){
return 1;/*Checks to see if player has won across any of the rows.*/
}
else if((board[0][0]==board[1][0] && board[0][0]==board[2][0]) || (board[0][1]==board[1][1] && board[0][1]==board[2][1]) || (board[0][2]==board[1][2] && board[0][2]==board[2][2])){
return 1;/*Checks to see if player has won down any columns.*/
}
else if((board[0][0]==board[1][1] && board[0][0]==board[2][2]) || (board[0][2]==board[1][1] && board[0][2]==board[2][0])){
return 1;/*Checks to see if player has won in a diagonal.*/
}
else{
return 0;
}
}
I'm running into an issue when trying to play the game though. After the first player chooses a "play spot" it thinks they have won already. Because of this I believe the issue is most likely due to an error in the wincheck function but I can't quite figure out what exactly is causing the issue. I'm a beginner programmer, so I apologize if this is kind of a dumb question. I really appreciate any help you can offer!
The problem is indeed with your wincheck function. It rightly checks that the three candidate cells are equal but does not check that those cells have been populated. That means the game will be detected as won even before a move is made (since all cells are set to -, a simple equality check will pass).
It's therefore not enough to do just the equality check, you also have to ensure that at least one of those cells has been set to a real player.
You can also make your code a bit more readable with a little refactoring, something like:
// Returns the actual winner, or '-' if none. Needs x/y start cell
// and x/y deltas (direction, basically).
int checkOneWinPossibility(char board[3][3], int x, int y, int xd, int yd) {
// Check all no-winner scenarios, return winner only if they all fail.
if (board[x][y] == '-') return '-';
if (board[x][y] != board[x+xd][y+yd]) return '-';
if (board[x][y] != board[x+xd*2][y+yd*2]) return '-';
return board[x][y];
}
int checkAllWinPossibilities(char board[3][3]){
int winner;
// Horizontals.
if ((winner = checkOneWinner(board, 0, 0, 0, 1)) != '-') return winner;
if ((winner = checkOneWinner(board, 1, 0, 0, 1)) != '-') return winner;
if ((winner = checkOneWinner(board, 2, 0, 0, 1)) != '-') return winner;
// Verticals.
if ((winner = checkOneWinner(board, 0, 0, 1, 0)) != '-') return winner;
if ((winner = checkOneWinner(board, 0, 1, 1, 0)) != '-') return winner;
if ((winner = checkOneWinner(board, 0, 2, 1, 0)) != '-') return winner;
// Diagonals.
if ((winner = checkOneWinner(board, 0, 0, 1, 1)) != '-') return winner;
if ((winner = checkOneWinner(board, 2, 0, -1, 1)) != '-') return winner;
return '-';
}
That last diagonal check could be combined with the return statement just by doing:
return checkOneWinner(board, 2, 0, -1, 1);
but I prefer (being slightly OCD) to leave it as is for consistency :-)
They also both return the actual winner rather than just an indication that there is a winner. You may not need that information since it will obviously be the last player that moved, but there's no probably no substantial harm in returning the extra information.
Related
I'm new to C and I'm trying to make a tic-tac-toe game for my college project and I'm struggling on how to reset my array in my game.
Every time I play again it does not reset the array. Can anyone help me with this?
Here is the code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
char space[3][3] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'}
};
void board();
int checkWin();
int game();
void reset();
int main(){
int choice = -1;
do{
printf("\n\n\n\n\n\n\n\t\t\t ================\n");
printf("\t\t\t Tic Tac Toe\n");
printf("\t\t\t ================\n");
printf("\t\t -----------Menu-----------\n\n");
printf("\t\t 1. Play\n");
printf("\t\t 2. Exit\n");
scanf("%d", &choice);
switch(choice){
case 1: game();
break;
case 2: printf("Goodbye!!");
exit(0);
break;
default: printf(".......Wrong Key !.......Try Again!......");
break;
}
}while(choice != 0);
}
int game(){
int player = 1, i, choice;
char mark;
do
{
system("cls");
board();
player = (player % 2) ? 1 : 2;
printf("Player %d, enter a number: ", player);
scanf("%d", &choice);
mark = (player == 1) ? 'X' : 'O';
if (choice == 1)
space[0][0] = mark;
else if (choice == 2)
space[0][1] = mark;
else if (choice == 3)
space[0][2] = mark;
else if (choice == 4)
space[1][0] = mark;
else if (choice == 5)
space[1][1] = mark;
else if (choice == 6)
space[1][2] = mark;
else if (choice == 7)
space[2][0] = mark;
else if (choice == 8)
space[2][1] = mark;
else if (choice == 9)
space[2][2] = mark;
else
{
printf("Invalid move ");
player--;
getch();
}
i = checkWin();
player++;
}while (i == - 1);
board();
reset();
if (i == 1)
printf("==>\aPlayer %d win \n\n", --player);
else
printf("==>\aGame draw\n\n");
getch();
return 0;
}
int checkWin(){
if (space[0][0] == space[0][1] && space[0][1] == space[0][2])
return 1;
else if (space[1][0] == space[1][1] && space[1][1] == space[1][2])
return 1;
else if (space[2][0] == space[2][1] && space[2][1] == space[2][2])
return 1;
else if (space[0][0] == space[1][0] && space[1][0] == space[2][0])
return 1;
else if (space[0][1] == space[1][1] && space[1][1] == space[2][1])
return 1;
else if (space[0][2] == space[1][2] && space[1][2] == space[2][2])
return 1;
else if (space[0][0] == space[1][1] && space[1][1] == space[2][2])
return 1;
else if (space[0][2] == space[1][1] && space[1][1] == space[2][0])
return 1;
else if (space[0][0] != space[0][0] && space[0][1] != space[0][1] && space[0][2] != space[0][2] &&
space[1][0] != space[1][0] && space[1][1] != space[1][1] && space[1][2] != space[1][2] && space[2][0]
!= space[2][0] && space[2][1] != space[2][1] && space[2][2] != space[2][1])
return 0;
else
return - 1;
}
void reset(){
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
space[i][j] = 0;
}
}
}
void board(){
system("cls");
printf("\n\n\tTic Tac Toe\n\n");
printf("Player 1 (X) - Player 2 (O)\n\n\n");
printf(" | | \n");
printf(" %c | %c | %c \n", space[0][0], space[0][1], space[0][2]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", space[1][0], space[1][1], space[1][2]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", space[2][0], space[2][1], space[2][2]);
printf(" | | \n\n");
}
I tried using for loop but it does not work; how can I solve this?
void reset(){
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
space[i][j] = 0;
}
}
}
Your reset function is filling the entire 3x3 board matrix with zeros; these represent the nul character, not the character representing the '0' digit. Those nul characters aren't printed (and cannot be), so the board looks 'wrong' after a reset.
However, simply changing the space[i][j] = 0; line to space[i][j] = '0'; won't work! Although you will then initially see a board full of 0 digits, the way your checkWin() function works will then ensure that "Player 1" will have won the new game immediately after their first move, because there will already be rows/columns/diagonals of three identical characters.
So, to get the original ('1' thru '9') display, write your reset() function as below. (Note that the C Standard requires that the characters representing the numerical digits be in order and contiguous, so adding a value of 1 thru 9 to the '0' character will yield the appropriate digit character.)
void reset()
{
int number = 1;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
space[i][j] = number++ + '0';
}
}
}
Alternatively, you can just declare and initialize a new 'board array' with the data in it, then just use memcpy to rest the space array with the contents of that:
#include <string.h> // For "memcpy"
void reset()
{
char empty[3][3] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'} };
memcpy(space, empty, sizeof(space));
}
Note, also that all the tests in the following statement are wrong:
else if (space[0][0] != space[0][0] && space[0][1] != space[0][1] && space[0][2] != space[0][2] &&
space[1][0] != space[1][0] && space[1][1] != space[1][1] && space[1][2] != space[1][2] && space[2][0]
!= space[2][0] && space[2][1] != space[2][1] && space[2][2] != space[2][1])
Each one of these is testing if an element is not equal to itself. This can never be true, so that else if block (the return 0; line) is never executed. But you don't actually need it, so you can just delete that block.
I'm learning C at school, and as homework I have to write the tictactoe game. No problem with the "algorithm", but I do not understand why if I change the order of the variables declaration, the program output drastically changes or even the programme stops working. For example, if I swap line 12 with line 13, the element of the array coord change values at random points of the programme. Can someone explain me why this happen?
#include <stdio.h>
#define DIM 3
#define MAX 11
int main(void) {
char c;
int state = 0; //Variable for the switch case
int nC, nR; //Variables used to count how many X or O there are in the rows and columns of the grid
int i, j;
int coord[2] = {0, 0}; //Array for the coordinates
char grid[DIM][DIM]; //Grid 3x3
char player1[MAX] = "", player2[MAX] = ""; //Name of the players
printf("Player 1, insert your name (max 10 characters): ");
gets(player1);
fflush(stdin);
printf("Player 2, insert your name (max 10 characters): ");
gets(player2);
for (i = 0; i < DIM; i++) { //Inizialize the grid with '.'
for (j = 0; j < DIM; j++) {
grid[i][j] = '.';
printf("%3c", grid[i][j]);
if (j == 0 || j == 1) printf(" |");
}
if (i == 0 || i == 1) printf("\n- - - - - - - -\n");
}
do{
switch (state) {
case 0: //State 0: Player 1 is asked for the coordinates corresponding to the position where you want to insert the X symbol
printf("\n%s your turn: ", player1);
scanf("%d %d", &coord[1], &coord[2]);
if (grid[coord[1] - 1][coord[2] - 1] == '.' && grid[coord[1] - 1][coord[2] - 1] != 'O') { //Check that the selected coordinates are free. Otherwise it prints an error message
grid[coord[1] - 1][coord[2] - 1] = 'X';
c = 'X';
state = 2;
}
else{
state = 0;
printf("Invalid coordinates!\n");
}
break;
case 1: //State 1: Player 2 is asked for the coordinates corresponding to the position where you want to insert the O symbol
printf("\n%s your turn: ", player2);
scanf("%d %d", &coord[1], &coord[2]);
if (grid[coord[1] - 1][coord[2] - 1] == '.' && grid[coord[1] - 1][coord[2] - 1] != 'X') { //Check that the selected coordinates are free. Otherwise it prints an error message
grid[coord[1] - 1][coord[2] - 1] = 'O';
c = 'O';
state = 2;
}
else{
printf("Invalid coordinates!\n");
state = 1;
}
break;
case 2: //State 2: Check if there a right combination of X or O
printf("\n");
for (i = 0; i < DIM; i++) {
for (j = 0; j < DIM; j++) {
printf("%3c", grid[i][j]);
if(j == 0 || j == 1) printf(" |");
}
if (i == 0 || i == 1) printf("\n- - - - - - - -\n");
}
nC = 0;
nR = 0;
i = coord[1] - 1;
for (j = 0; j < DIM; j++) {
if(grid[i][j] != c){
break;
}
else{
nR++;
}
}
j = coord[2] - 1;
for (i = 0; i < DIM; i++) {
if (grid[i][j] != c) {
break;
}
else{
nC++;
}
}
if (nC == 3 || nR == 3) state = 3;
else if (c == 'X') state = 1;
else state = 0;
break;
case 3:
if (c == 'X') printf("\n%s IS THE WINNER!\n", player1);
else printf("\n%s IS THE WINNER!\n", player2);
return 0;
break;
}
} while (1);
}
In C, array indices for an array with n elements run from 0 to nā1.
int coord[2] = {0, 0}; defines coord to have two elements, so their indices are 0 and 1.
Throughout the code, coord[1] and coord[2] are used. coord[2] is outside the defined array, so the behavior of the program is not defined by the C standard.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int generaterandomno(int n)
{
srand(time(NULL));
return rand() % n;
}
int greater(char char1, char char2)
{
//For Rock, Paper, Scissors - Returns 1 if c1>c2 and 0 otherwise. If c1 == c2 it will return -1
if (char1 == char2)
{
return -1;
}
else if ((char1 == 'r') && (char2 == 's'))
{
return 1;
}
else if ((char2 == 'r') && (char1 == 's'))
{
return 0;
}
else if ((char1 == 'p') && (char2 == 'r'))
{
return 1;
}
else if ((char2 == 'p') && (char1 == 'r'))
{
return 0;
}
else if ((char1 == 's') && (char2 == 'p'))
{
return 1;
}
else if ((char2 == 's') && (char1 == 'p'))
{
return 0;
}
}
int main()
{
int playerscore = 0, compscore = 0, temp;
char playerchar, compchar;
char dict[] = {'r', 'p', 's'};
printf("Welcome to The Rock, Paper, Scissors Game, I hope you will enjoy\n");
for (int i = 0; i < 3; i++)
{
// Take Player 1's input
printf("Player 1:\n");
printf("Choose 1 for Rock, 2 for Paper and 3 for Scissors\n");
scanf("%d", &temp);
getchar();
playerchar = dict[temp - 1];
printf("You chose %c\n\n", playerchar);
// Generate computer's input
printf("Computer's Turn:\n");
printf("Choose 1 for Rock, 2 for Paper and 3 for Scissors\n");
temp = generaterandomno(3) + 1;
compchar = dict[temp - 1];
printf("Computer chose %c\n\n", compchar);
// Compare the scores
if (greater(compchar, playerchar) == 1)
{
compscore += 1;
printf("Computer got it!!!\n");
}
else if (greater(compchar, playerchar) == -1)
{
compscore += 1;
playerscore += 1;
printf("It's a Draw!!!\n");
}
else
{
playerscore += 1;
printf("You got it!!!\n");
}
printf("You: %d\nComp: %d\n\n",playerscore, compscore);
}
if (playerscore > compscore)
{
printf("----------------------\n");
printf("------You Won!!!------\n");
printf("----------------------\n");
}
else if (compscore > playerscore)
{
printf("---------------------\n");
printf("---Computer Won!!!---\n");
printf("---------------------\n");
}
else
{
printf("----------------------\n");
printf("----It's a Draw!!!----\n");
printf("----------------------\n");
}
return 0;
}
char dict[] = {'r', 'p', 's'};
I have a problem with this š how can I write multiple characters inside an array in c please get me a solution. I want to write rock paper and scissors replacing this please get a solution for me.....
I think what you are asking is about outputting 'rock' instead of 'r' when confirming the choice.
You could create a 2 dimensional array to hold the strings instead of a one dimensional array. For example...
char rps[][] = { "rock", "paper", "scissors" };
This would allow you to get at both the initials for example...
rps[0][0] would be 'r'
or the whole string...
rps[0] is "rock"
The important thing to note is that a string is just a char array with a null terminator.
These links will help explain a bit more.
https://www.programiz.com/c-programming/c-strings
https://www.codingame.com/playgrounds/14213/how-to-play-with-strings-in-c/array-of-c-string
trying to learn about computer game players to familiarise myself with AI. I understand how minimax works in theory but cant get my head around how this code I found online works.
can someone explain the minimax fruction/computer move function (lines 38-78)to me.
credit: https://gist.github.com/MatthewSteel/3158579
thanks
char gridChar(int i) {
switch(i) {
case -1:
return 'X';
case 0:
return ' ';
case 1:
return 'O';
}
}
void draw(int b[9]) {
printf(" %c | %c | %c\n",gridChar(b[0]),gridChar(b[1]),gridChar(b[2]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[3]),gridChar(b[4]),gridChar(b[5]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[6]),gridChar(b[7]),gridChar(b[8]));
}
int win(const int board[9]) {
//determines if a player has won, returns 0 otherwise.
unsigned wins[8][3] = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}};
int i;
for(i = 0; i < 8; ++i) {
if(board[wins[i][0]] != 0 &&
board[wins[i][0]] == board[wins[i][1]] &&
board[wins[i][0]] == board[wins[i][2]])
return board[wins[i][2]];
}
return 0;
}
int minimax(int board[9], int player) {
//How is the position like for player (their turn) on board?
int winner = win(board);
if(winner != 0) return winner*player;
move = -1;
int score = -2;//Losing moves are preferred to no move
int i;
for(i = 0; i < 9; ++i) {//For all moves,
if(board[i] == 0) {//If legal,
board[i] = player;//Try the move
int thisScore = -minimax(board, player*-1);
if(thisScore > score) {
score = thisScore;
move = i;
}//Pick the one that's worst for the opponent
board[i] = 0;//Reset board after try
}
}
if(move == -1) return 0;
return score;
}
void computerMove(int board[9]) {
int move = -1;
int score = -2;
int i;
for(i = 0; i < 9; ++i) {
if(board[i] == 0) {
board[i] = 1;
int tempScore = -minimax(board, -1);
board[i] = 0;
if(tempScore > score) {
score = tempScore;
move = i;
}
}
}
//returns a score based on minimax tree at a given node.
board[move] = 1;
}
void playerMove(int board[9]) {
int move = 0;
do {
printf("\nInput move ([0..8]): ");
scanf("%d", &move);
printf("\n");
} while (move >= 9 || move < 0 && board[move] == 0);
board[move] = -1;
}
int main() {
int board[9] = {0,0,0,0,0,0,0,0,0};
//computer squares are 1, player squares are -1.
printf("Computer: O, You: X\nPlay (1)st or (2)nd? ");
int player=0;
scanf("%d",&player);
printf("\n");
unsigned turn;
for(turn = 0; turn < 9 && win(board) == 0; ++turn) {
if((turn+player) % 2 == 0)
computerMove(board);
else {
draw(board);
playerMove(board);
}
}
switch(win(board)) {
case 0:
printf("A draw. How droll.\n");
break;
case 1:
draw(board);
printf("You lose.\n");
break;
case -1:
printf("You win. Inconceivable!\n");
break;
}
}
Here is the essence of minimax:
int minimax(int board[9], int player) {
// ....
for(i = 0; i < 9; ++i) { //For all moves,
// ....
int thisScore = -minimax(board, player*-1);
}
}
Go through each possible move, and for each such possible move, turn the board around, pretend to be the other player (that's the player*-1 part), and try each possible move. thisScore is set to the negative return value from the recursive call to minimax, since good for the other player equals bad for ourselves.
computerMove just goes through all the possible moves, calls minimax for each such possible move, and uses the one with the best result.
I am building a tic tac toe game as an assignment which will put two users vs each other. I have gotten the game to run but a requirement of the game is to "ask the user to enter their move with integers in between 0 and 2, inclusive, specifying the row and column of the square to place a piece." As I have it know the user chooses a number 1-9 and enters that but based on the question i have to format it to get two numbers 1 specifying row and the other column eg 1 = 0,0 2 = 0,1 and so on. I am fairly new to programming can anyone help me implement this or point me in the right direction; also any comments or changes to the main program to improve it is welcomed.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int winner = 0, count = 0;
int data[9], index, letter, user, flag, i, k;
for (i = 0; i < 9; i++)
data[i] = ' ';
while (count < 9) {
flag = 0;
printf("\n\n");
printf("\t\t\t %c | %c | %c \n", data[0], data[1], data[2]);
printf("\t\t\t----+----+----\n");
printf("\t\t\t %c | %c | %c \n", data[3], data[4], data[5]);
printf("\t\t\t----+----+---\n");
printf("\t\t\t %c | %c | %c \n\n", data[6], data[7], data[8]);
if (count % 2 == 0) {
letter = 'X';
user = 1;
} else {
letter = 'O';
user = 2;
}
printf("User %d enter your move (1-9):", user);
scanf("%d", &index);
if (index < 1 || index > 9) {
printf("Allowed index is 1 to 9!!\n");
continue;
}
if (data[index - 1] == 'X' || data[index - 1] == 'O') {
printf("Position already occupied!!\n");
continue;
}
data[index - 1] = letter;
count++;
for (i = 0; i < 9; i++) {
if (i % 3 == 0)
flag = 0;
if (data[i] == letter)
flag++;
if (flag == 3) {
winner = 1;
goto win;
}
}
flag = 0;
for (i = 0; i < 3; i++) {
for (k = i; k <= i + 6; k = k + 3) {
if (data[k] == letter)
flag++;
}
if (flag == 3) {
winner = 1;
goto win;
}
flag = 0;
}
if ((data[0] == letter && data[4] == letter && data[8] == letter) ||
(data[2] == letter && data[4] == letter && data[6] == letter)) {
winner = 1;
goto win;
}
}
win:
printf("\n\n");
printf("\t\t\t %c | %c | %c \n", data[0], data[1], data[2]);
printf("\t\t\t----+----+----\n");
printf("\t\t\t %c | %c | %c \n", data[3], data[4], data[5]);
printf("\t\t\t----+----+---\n");
printf("\t\t\t %c | %c | %c \n\n", data[6], data[7], data[8]);
if (winner) {
printf("User %d is the winner. Congrats!!\n", user);
} else {
printf("The game is a tie\n");
}
return 0;
}
Instead of the index variable you have, you'll want an x variable and a y variable. Then, instead of scanf("%d", &index);, you could do scanf("%d,%d", &x, &y); (the player will have to enter a comma in this example.)
Then, assuming we have a variable called "board_width" which equals 3 (because I like to avoid magic numbers,) we could get the position from the user's input using data[(y * board_width) + x]