Generating a new chess project step after step

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Generating a new chess project step after step

Post by Uri Blass »

my first steps are not related to chess and only to reading input
I expect to have many steps unlike the winglet source that enter a lot of code without explanation.

I use the winglet page as a guide line but there are some differences.
I think steps should be written in a way that even people who know nothing about C can understand easily what I do so there are going to be a lot of comments in the first steps that I am going to delete later.

I will write every step as a new post and basically the change in code in one step is going to be only a small number of lines.
Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Generating a new chess project step after step

Post by Uri Blass »

step 1:do nothing but have a main function that compile
I call the file main.cpp

note that it is different than the code in
http://web.archive.org/web/201201120650 ... 20commands
that has
int main(int argc, char *argv[])



content of main.cpp:

int main()
{
return 0;
}
Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Generating a new chess project step after step

Post by Uri Blass »

step 2:

step 2: the program should write something like my program and wait for the user to print something with enter to exit

content of main.cpp:

#include <iostream> //I need it for the computer to understand the std function
void readCommands()
{
int nextc;//next command
while ((nextc = getc(stdin)) != EOF)//waiting for the user to print something with enter to finish at this point
{
//the program get here only after the user clicked return and entering chars without return does nothing
return;//later I will do something more complicated to do different things for different input
}
}
int main()
{
//comments because I assume the readers do not know C(I will delete them later)
//comment 1 std:cout print something
//comment 2 std::cout << "my program"; print the words my program without a new line
//comment 3 std::cout<<std::endl; print a new line without printing something else
std::cout << "my program" << std::endl;// do both printing my program and printing a new line in one line of code
readCommands();//calling a function that is defined in the file(I will later put the function in a different file)
return 0;
}
Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Generating a new chess project step after step

Post by Uri Blass »

step 3

#include <iostream> //I need it for the computer to understand the std function
#include <stdio.h> //I need it for the computer to understand printf(I do not know the advantage of ctd::cout relative to printf and I prefer using printf)
void readCommands()
{
int nextc;//next command
while ((nextc = getc(stdin)) != EOF)//waiting for the user to print something with enter to going into the loop at this point
{
//the program finished to calculate getc because the user entered some chars and clicked enter and got an input
//nextc is the first char that the user entered
if (nextc=='q') return;//if the user entered the char q the program simply quit.
printf("%c", nextc);//printf print the char in nextc and %c is for printing it as char I could use %d to print it as int
//The program now go to the while command and nextc become the next char that the user entered.
//last char that the user entered is a new line and after reading it the program need to wait for the user to enter a new char to calculate getc
}
}
int main()
{
std::cout << "my program" << std::endl;// do both printing my program and printing a new line in one line of code
readCommands();//calling a function that is defined in the file(I will later put the function in a different file)
return 0;
}
Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Generating a new chess project step after step

Post by Uri Blass »

step 4:

#include <iostream> //I need it for the computer to understand the std function
#include <stdio.h> //I need it for the computer to understand printf(I do not know the advantage of ctd::cout relative to printf and I prefer using printf)
int CMD_BUFF_COUNT = 0;//global variable to count number of chars in the buffer (addition 1 in step 4).
#define MAX_CMD_BUFF 256//max chars in the command that the program can get(addition 2 in step 4)
char CMD_BUFF[MAX_CMD_BUFF];//global array to include the content of the command buffer I will later put it in a special file of global variables
//and same for previous variables but as long as the program is small it is not a problem. (addition 3 in step 4)

//added doCommand in step 4(addition 4 in step 4)
int doCommand(const char *buf)
{
//this function now only look at the first char of the input and return 0 only if it is q
CMD_BUFF_COUNT = '\0';//I need to do it before finishing this function if I do not quit
//because I want number of chars in the buffer to be 0 before reading a new command
if (CMD_BUFF[0] == 'q')
return 0;
return 1;
}
void readCommands()
{
int nextc;//next command
while ((nextc = getc(stdin)) != EOF)//waiting for the user to print something with enter to going into the loop at this point
{
//the program finished to calculate getc because the user entered some chars and clicked enter and got an input
//nextc is the first char that the user entered
//next lines are addition 5 in step 4 that replaced the old code in step 3 that quit if I entered q
//the difference is that now I quit only if the first letter of the string the user entered is q and
//I also memorize the string the user entered in CMD_BUFF array to allow me to analyze it in the function doCommand that I added.
if (nextc == '\n') //we are at the end of the input that the user entered
{
CMD_BUFF[CMD_BUFF_COUNT] = '\0';
while (CMD_BUFF_COUNT)
if (!doCommand(CMD_BUFF)) return;
}
else
{
//we are not at the end of the user input so we put the user input in the buffer in case that we have space
if (CMD_BUFF_COUNT >= MAX_CMD_BUFF - 1)
{
std::cout << "Warning: command buffer full !! " << std::endl;
CMD_BUFF_COUNT = 0;//we do not have space so we practically delete the user input and start from scratch.
}
CMD_BUFF[CMD_BUFF_COUNT++] = nextc;
/*this command basically first put the new char in the CMD_BUFF array and later increase the value of CMD BUFF and later increase
the count by one and is equivalent to the following commands
CMD_BUFF[CMD_BUFF_COUNT]=nextc;
CMD_BUFF_COUNT++;//increase the value of the variable by 1.
*/
}
}
}
int main()
{
std::cout << "my program" << std::endl;// do both printing my program and printing a new line in one line of code
readCommands();//calling a function that is defined in the file(I will later put the function in a different file)
return 0;
}
Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Generating a new chess project step after step

Post by Uri Blass »

Note:in old posts you can see the code like I write it in case that you try to reply with a quote(otherwise you do not see the spaces in the lines and all the lines start from the same place).

Now things are going to be different because I use the option code in the post.

step 5:

Code: Select all

#include <iostream> //I need it for the computer to understand the std function
#include <stdio.h> //I need it for the computer to understand printf(I do not know the advantage of ctd::cout relative to printf and I prefer using printf)
int CMD_BUFF_COUNT = 0;//global variable to count number of chars in the buffer (addition 1 in step 4).
#define MAX_CMD_BUFF 256//max chars in the command that the program can get(addition 2 in step 4)
char CMD_BUFF[MAX_CMD_BUFF];//global array to include the content of the command buffer  I will later put it in a special file of global variables 
//and same for previous variables but as long as the program is small it is not a problem.  (addition 3 in step 4)

//added doCommand in step 4(addition 4 in step 4)
int doCommand(const char *buf)
{
	//this function now only look at the string of the input and return 0 only if it is identical to the word exit or quit
	CMD_BUFF_COUNT = '\0';//I need to do it before finishing this function if I do not quit
	//because I want number of chars in the buffer to be 0 before reading a new command
	//this is the only change that I did in step 5 relative to step 4 and it look at the all string and return 0 only if the string is equal to exit or quit
	if ((!strcmp(buf, "exit")) || (!strcmp(buf, "quit")))
	{
		CMD_BUFF_COUNT = '\0';
		return 0;
	}
	return 1;
}
void readCommands()
{
	int nextc;//next command
	while ((nextc = getc(stdin)) != EOF)//waiting for the user to print something with enter to going into the loop at this point
	{
		//the program finished to calculate getc because the user entered some chars and clicked enter and got an input 
		//nextc is the first char that the user entered
		//next lines are addition 5 in step 4 that replaced the old code in step 3 that quit if I entered q 
		//the difference is that now I quit only if the first letter of the string the user entered is q and 
		//I also memorize the string the user entered in CMD_BUFF array to allow me to analyze it in the function doCommand that I added.
		if (nextc == '\n') //we are at the end of the input that the user entered
		{
			CMD_BUFF[CMD_BUFF_COUNT] = '\0';
			while (CMD_BUFF_COUNT)
				if (!doCommand(CMD_BUFF)) return;
		}
		else
		{
			//we are not at the end of the user input so we put the user input in the buffer in case that we have space
			if (CMD_BUFF_COUNT >= MAX_CMD_BUFF - 1)
			{
				std::cout << "Warning: command buffer full !! " << std::endl;
				CMD_BUFF_COUNT = 0;//we do not have space so we practically delete the user input and start from scratch.
			}
			CMD_BUFF[CMD_BUFF_COUNT++] = nextc;
			/*this command basically first put the new char in the CMD_BUFF array and later increase the value of CMD BUFF and later increase
			  the count by one and is equivalent to the following commands
			  CMD_BUFF[CMD_BUFF_COUNT]=nextc;
			  CMD_BUFF_COUNT++;//increase the value of the variable by 1.
			*/
		}
	}
}
int main()
{
	std::cout << "my program" << std::endl;// do both printing my program and printing a new line in one line of code
	readCommands();//calling a function that is defined in the file(I will later put the function in a different file)
	return 0;
}
Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Generating a new chess project step after step

Post by Uri Blass »

in step 6 I deleted some comments from previous steps and also change int in do_command to BOOLTYPE;

Code: Select all

#include <iostream> 
#include <stdio.h> 
int CMD_BUFF_COUNT = 0;
#define MAX_CMD_BUFF 256
typedef int BOOLTYPE;// addition 1 in step 6(doCommand return int but is a logical function that practically return true or false
//false mean that we exit the program so I change the int to BoolType and the 1 or 0 to true and false to make the code more clear
char CMD_BUFF[MAX_CMD_BUFF]; 


BOOLTYPE doCommand(const char *buf)//change 2 from int to BOOLTYPE in step 6
{
	//this function now only look at the string of the input and return 0 only if it is identical to the word exit or quit
	CMD_BUFF_COUNT = '\0';
	if ((!strcmp(buf, "exit")) || (!strcmp(buf, "quit")))
	{
		CMD_BUFF_COUNT = '\0';
		return false;  //change 3 from 0 to false in step 6
	}
	return true; //change 4 from 1 to true in step 6
}
void readCommands()
{
	int nextc;//next command
	while ((nextc = getc(stdin)) != EOF)//waiting for the user to print something with enter to going into the loop at this point
	{
		//the program finished to calculate getc because the user entered some chars and clicked enter and got an input 
		//nextc is the first char that the user entered
		if (nextc == '\n') //we are at the end of the input that the user entered
		{
			CMD_BUFF[CMD_BUFF_COUNT] = '\0';
			while (CMD_BUFF_COUNT)
				if (!doCommand(CMD_BUFF)) return;
		}
		else
		{
			//we are not at the end of the user input so we put the user input in the buffer in case that we have space
			if (CMD_BUFF_COUNT >= MAX_CMD_BUFF - 1)
			{
				std::cout << "Warning: command buffer full !! " << std::endl;
				CMD_BUFF_COUNT = 0;//we do not have space so we practically delete the user input and start from scratch.
			}
			CMD_BUFF[CMD_BUFF_COUNT++] = nextc;
		}
	}
}
int main()
{
	std::cout << "my program" << std::endl;// do both printing my program and printing a new line in one line of code
	readCommands();//calling a function that is defined in the file(I will later put the function in a different file)
	return 0;
}
Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Generating a new chess project step after step

Post by Uri Blass »

In step 7 I added a file of definitions and have them only in a special file and not in the main program.
I needed to add in main.cpp the line #include "defines.h" so the computer know that defines.h is part of the project when it is in main.cpp

code of main.cpp

Code: Select all

#include <iostream> 
#include <stdio.h> 
#include "defines.h"//added this file in step 7 and copied things that I did in step 6 to defines.h
int CMD_BUFF_COUNT = 0;
char CMD_BUFF[MAX_CMD_BUFF]; 


BOOLTYPE doCommand(const char *buf)//change 2 from int to BOOLTYPE in step 6
{
	//this function now only look at the string of the input and return 0 only if it is identical to the word exit or quit
	CMD_BUFF_COUNT = '\0';
	if ((!strcmp(buf, "exit")) || (!strcmp(buf, "quit")))
	{
		CMD_BUFF_COUNT = '\0';
		return false;  //change 3 from 0 to false in step 6
	}
	return true; //change 4 from 1 to true in step 6
}
void readCommands()
{
	int nextc;//next command
	while ((nextc = getc(stdin)) != EOF)//waiting for the user to print something with enter to going into the loop at this point
	{
		//the program finished to calculate getc because the user entered some chars and clicked enter and got an input 
		//nextc is the first char that the user entered
		if (nextc == '\n') //we are at the end of the input that the user entered
		{
			CMD_BUFF[CMD_BUFF_COUNT] = '\0';
			while (CMD_BUFF_COUNT)
				if (!doCommand(CMD_BUFF)) return;
		}
		else
		{
			//we are not at the end of the user input so we put the user input in the buffer in case that we have space
			if (CMD_BUFF_COUNT >= MAX_CMD_BUFF - 1)
			{
				std::cout << "Warning: command buffer full !! " << std::endl;
				CMD_BUFF_COUNT = 0;//we do not have space so we practically delete the user input and start from scratch.
			}
			CMD_BUFF[CMD_BUFF_COUNT++] = nextc;
		}
	}
}
int main()
{
	std::cout << "my program" << std::endl;// do both printing my program and printing a new line in one line of code
	readCommands();//calling a function that is defined in the file(I will later put the function in a different file)
	return 0;
}
code of defines.h(note that the first line is not something that I wrote and the compiler added it automatically
and based on understanding it means that I can avoid the #ifndef #define that winglet use in many files)

Code: Select all

#pragma once
#define MAX_CMD_BUFF 256
typedef int BOOLTYPE;// addition 1 in step 6(doCommand return int but is a logical function that practically return true or false
//false mean that we exit the program so I change the int to BoolType and the 1 or 0 to true and false to make the code more clear
Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Generating a new chess project step after step

Post by Uri Blass »

In step 8 I added a file of global variables

I have now the following code(I did not change defines.h so I did not give it again)
1)main.cpp

Code: Select all

#include <iostream> 
#include <stdio.h> 
#include "defines.h"//added this file in step 7  
#include "globals.h"//added this file in step 8 


BOOLTYPE doCommand(const char *buf)
{
	//this function now only look at the string of the input and return false only if it is identical to the word exit or quit
	CMD_BUFF_COUNT = '\0';
	if ((!strcmp(buf, "exit")) || (!strcmp(buf, "quit")))
	{
		CMD_BUFF_COUNT = '\0';
		return false;  
	}
	return true;
}
void readCommands()
{
	int nextc;//next command
	while ((nextc = getc(stdin)) != EOF)//waiting for the user to print something with enter to going into the loop at this point
	{
		//the program finished to calculate getc because the user entered some chars and clicked enter and got an input 
		//nextc is the first char that the user entered
		if (nextc == '\n') //we are at the end of the input that the user entered
		{
			CMD_BUFF[CMD_BUFF_COUNT] = '\0';
			while (CMD_BUFF_COUNT)
				if (!doCommand(CMD_BUFF)) return;
		}
		else
		{
			//we are not at the end of the user input so we put the user input in the buffer in case that we have space
			if (CMD_BUFF_COUNT >= MAX_CMD_BUFF - 1)
			{
				std::cout << "Warning: command buffer full !! " << std::endl;
				CMD_BUFF_COUNT = 0;//we do not have space so we practically delete the user input and start from scratch.
			}
			CMD_BUFF[CMD_BUFF_COUNT++] = nextc;
		}
	}
}
int main()
{
	std::cout << "my program" << std::endl;// do both printing my program and printing a new line in one line of code
	readCommands();//calling a function that is defined in the file(I will later put the function in a different file)
	return 0;
}
2)globals.h

Code: Select all

#pragma once
#include "defines.h"//needed to include it so the compiler can know that MAX_CMD_BUFF is the constant I defined there
char CMD_BUFF[MAX_CMD_BUFF];
int CMD_BUFF_COUNT = 0;
Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Generating a new chess project step after step

Post by Uri Blass »

In step 9 I add a file with the name protos.h that include all the functions that I use in the program except the main function
explanation in the winglet site
"protos.h contains the prototypes of all functions (we'll keep them sorted alphabetically). This ensures that the compiler already knows how a function looks like, before actually having seen the code. We'll start with prototyping the two first functions:"

here is the code after step 9(changed only main and added protos so do not repeat the rest)

content of main.cpp

Code: Select all

#include <iostream> 
#include <stdio.h> 
#include "defines.h"//added this file in step 7  
#include "globals.h"//added this file in step 8 
#include "protos.h"//added this file in step 9

BOOLTYPE doCommand(const char *buf)
{
	//this function now only look at the string of the input and return false only if it is identical to the word exit or quit
	CMD_BUFF_COUNT = '\0';
	if ((!strcmp(buf, "exit")) || (!strcmp(buf, "quit")))
	{
		CMD_BUFF_COUNT = '\0';
		return false;  
	}
	return true;
}
void readCommands()
{
	int nextc;//next command
	while ((nextc = getc(stdin)) != EOF)//waiting for the user to print something with enter to going into the loop at this point
	{
		//the program finished to calculate getc because the user entered some chars and clicked enter and got an input 
		//nextc is the first char that the user entered
		if (nextc == '\n') //we are at the end of the input that the user entered
		{
			CMD_BUFF[CMD_BUFF_COUNT] = '\0';
			while (CMD_BUFF_COUNT)
				if (!doCommand(CMD_BUFF)) return;
		}
		else
		{
			//we are not at the end of the user input so we put the user input in the buffer in case that we have space
			if (CMD_BUFF_COUNT >= MAX_CMD_BUFF - 1)
			{
				std::cout << "Warning: command buffer full !! " << std::endl;
				CMD_BUFF_COUNT = 0;//we do not have space so we practically delete the user input and start from scratch.
			}
			CMD_BUFF[CMD_BUFF_COUNT++] = nextc;
		}
	}
}
int main()
{
	std::cout << "my program" << std::endl;// do both printing my program and printing a new line in one line of code
	readCommands();//calling a function that is defined in the file(I will later put the function in a different file)
	return 0;
}
content of protos.h

Code: Select all

#pragma once
BOOLTYPE    doCommand(const char *buf);
void        readCommands();