LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-13-2018, 01:49 AM   #1
LinaBellus
LQ Newbie
 
Registered: Dec 2018
Posts: 4

Rep: Reputation: Disabled
Tic tac toe using shared memory with SYS V IPC


Hey everyone.

I have some trouble finishing my first shared memory game. It's meant to play the well known Tic Tac Toe game between two processes. On the game board 1 stands for X's and 2 stands for O's.

Here's my first program:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include "header.h"


// function checks whether current player (process) won
int won(Table t)
{
	if (t.matrix[1] > 0) {
		if ((t.matrix[1] == t.matrix[2]) && (t.matrix[1] == t.matrix[3]))
			return 1;
		else
			if ((t.matrix[1] == t.matrix[4]) && (t.matrix[1] == t.matrix[7]))
			return 1;
			else
				if ((t.matrix[1] == t.matrix[5]) && (t.matrix[1] == t.matrix[9]))
				return 1;
	}
	if (t.matrix[9] > 0) {
		if ((t.matrix[9] == t.matrix[8]) && (t.matrix[9] == t.matrix[7]))
			return 1;
		else
			if ((t.matrix[9] == t.matrix[6]) && (t.matrix[9] == t.matrix[3]))
				return 1;
	}
	return 0;

}

//deletes shared memory
void removeshm(int shmid)
{
  	shmctl(shmid, IPC_RMID, NULL);
    printf("Shared memory deleted.\n");
}

//prints gameboard
void print_table(Table t)
{
	int i, j;
	printf("The board: \n");
	for (i=0; i < t.rows; i++) {
	    for (j=0; j < t.columns; j++) {
			printf("%d ",t.matrix[i * t.columns + j]);
	    }
		 printf("\n");
	}
	printf("\n");
}

int main(int argc, char *argv[])
{
	if( argc != 1 )
	{
		printf("Error: no parameter needed!\n");
		exit(0);
  	}
//for details, check header
	Table t;
	t.key = 100;
	t.rows = 3;
	t.columns = 3;

	t.matrix[10] = 0;

//connecting to shared memory
	int shmid = shmget(t.key, 9 * sizeof(int), IPC_CREAT | 0666);
	if (shmid == -1) {
			printf("Existing shared memory. \n");
		}
	else
		printf("Creating new shared memory \n");

	if ((t.matrix = shmat(shmid, NULL, 0)) == (void *) -1) {
			perror("Some error!");
			exit(1);
		}

	srand(getpid());

	while(1) {
//during even steps it's the turn of current player 
		if (t.matrix[10] % 2 == 0) {
			int pos = rand() % (9 - 1) + 1;
//player chooses a free field on the gameboard (field with value of zero) 
			 while (t.matrix[pos] != 0)
				 pos = rand() % (9 - 1) + 1;
			t.matrix[pos] = 1;
			t.matrix[10]++;
			printf("No. of current step: %d \n", t.matrix[10]);
			 print_table(t);
			if (won(t) == 1) {
				t.matrix[10] = 10;
				break;
			}
		}
		printf("\n\n");
		sleep(5);
		if (t.matrix[10] >= 9)
			break;
	}

	removeshm(100);
removeshm(shmid);
}
Second program:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include "header.h"

int won(Table t)
{
	if (t.matrix[1] > 0) {
		if ((t.matrix[1] == t.matrix[2]) && (t.matrix[1] == t.matrix[3]))
			return 1;
		else
			if ((t.matrix[1] == t.matrix[4]) && (t.matrix[1] == t.matrix[7]))
			return 1;
			else
				if ((t.matrix[1] == t.matrix[5]) && (t.matrix[1] == t.matrix[9]))
				return 1;
	}
	if (t.matrix[9] > 0) {
		if ((t.matrix[9] == t.matrix[8]) && (t.matrix[9] == t.matrix[7]))
			return 1;
		else
			if ((t.matrix[9] == t.matrix[6]) && (t.matrix[9] == t.matrix[3]))
				return 1;
	}
	return 0;

}

void removeshm(int shmid)
{
  	shmctl(shmid, IPC_RMID, NULL);
    printf("Shared memory deleted.\n");
}

void print_table(Table t)
{
	int i, j;
	printf("Board: \n");
	for (i=0; i < t.rows; i++) {
	    for (j=0; j < t.columns; j++) {
			 printf("%d ",t.matrix[i * t.columns + j]);
	    }
		printf("\n");
	}
	printf("\n");
}

int main(int argc, char *argv[])
{
	if( argc != 1 )
	{
		printf("ERROR: no parameter needed!\n");
		exit(0);
  	}


	Table t;
	t.key = 100;
	t.rows = 3;
	t.columns = 3;

int shmid = shmget(t.key, 9 * sizeof(int), IPC_EXCL);

	t.matrix = shmat(shmid, NULL, 0);

	while(1) {
//during odd steps it's the turn of second player 
	if (t.matrix[10] % 2 == 1) {
		int pos = rand() % (9 - 1) + 1;
		while (t.matrix[pos] != 0)
				pos = rand() % (9 - 1) + 1;
		 t.matrix[pos] = 2;
		t.matrix[10]++;
		 printf("No. of current step: %d \n", t.matrix[10]);
		 print_table(t);
		if (won(t) == 1) {
				t.matrix[10] = 10;
				break;
					}
	}
	sleep(5);
	if (t.matrix[10] >= 9)
				break;
	}
	shmdt(t.matrix);
	removeshm(100);
	removeshm(shmid);
}

Also, my header file contains the following:

Code:
typedef struct{
	int rows;
	int columns;
	key_t key;
	int *matrix;
}Table;
My problem is that both server and client stop with segmentation fault, and I don't know why. Program prints the gameboard at each step, but it won't stop once someone has won.
Could someone help me with this?

Thank you in advance.
 
Old 12-13-2018, 02:33 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
If you wish to use element matrix[10], then change the allocation size to 11*sizeof(int)

Also add more debug-printf, and after every printf use fflush(stdout).

Also pos should be between 1 and 9: pos = rand() % 9 + 1

Last edited by NevemTeve; 12-13-2018 at 02:36 AM.
 
Old 12-13-2018, 03:03 AM   #3
LinaBellus
LQ Newbie
 
Registered: Dec 2018
Posts: 4

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by NevemTeve View Post
If you wish to use element matrix[10], then change the allocation size to 11*sizeof(int)

Also add more debug-printf, and after every printf use fflush(stdout).

Also pos should be between 1 and 9: pos = rand() % 9 + 1
Thank you, I fixed that, but program stops at step no. 8 when there's only one free field left so I have to kill processes with CTRL + C.

Also, after editing and recompiling, the program won't even start the game, it stops with message "Creating new shared memory".

EDIT:
Okay, program seems to exit after 9 steps (when gameboard has no free fields left) and deletes shared memory segment, but it won't exit sooner in case one of the players wins.

Last edited by LinaBellus; 12-13-2018 at 03:19 AM. Reason: Fixed a few things.
 
1 members found this post helpful.
Old 12-13-2018, 04:29 AM   #4
LinaBellus
LQ Newbie
 
Registered: Dec 2018
Posts: 4

Original Poster
Rep: Reputation: Disabled
Okay, I fixed it, it works well now. The problem was firstly with the print_table function, both loops must start from 1 and not 0, and a few other smaller issues.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] bug when trying to find the win condition of tic-tac-toe in Common Lisp EnigmaticFellow Programming 2 04-26-2014 07:57 PM
LXer: Build tic-tac-toe with Kivy LXer Syndicated Linux News 0 04-22-2014 03:11 PM
multiplayer tic-tac-toe using semaphore... siya25 Linux - Newbie 5 03-12-2013 04:26 AM
creating an interoperable program for Tic tac toe sachitha Programming 2 08-25-2006 11:56 AM
searching "TIC TAC TOE" bash script LV-chronos Linux - Newbie 5 05-29-2005 02:20 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:45 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration