Jump to content


Check out our Community Blogs

Aereshaa

Member Since 07 Apr 2008
Offline Last Active Feb 19 2010 08:36 PM
-----

#515938 Really fast prime finder

Posted by Aereshaa on 14 October 2009 - 11:36 AM

This program outputs, for any number n, all primes < n. On my computer, it outputs all < 10000000 in 22 seconds wall clock time.:thumbup1:
#include "stdio.h"
#include "stdlib.h"

struct list {
	int i;
	struct list * next;
} *first, *last;

void add_prime(){
	int i=last->i+1;
	while(!check_prime(i))i++;
	last->next = malloc(sizeof(struct list));
	last=last->next;
	last->i=i;
	last->next=NULL;
	//printf("add %d",i);
}

int check_prime(int i){
	if(i>last->i*last->i)
		add_prime();
	struct list *p=first;
	while(i%p->i)
		if(p->next)
			p=p->next;
		else
			return 1;
	return 0;
}

int main(int argc,char ** argv){
	printf("%d\n",2);
	int lim;
	if(argc==1)lim=100;
	else sscanf(argv[1],"%d",&lim);
	first=last=malloc(sizeof(struct list));
	first->i=2;
	first->next = NULL;
	int i=2;
	while(++i<lim)
		if(check_prime(i))
			printf("%d\n",i);
}

It uses a linked list to store all primes that are necessary. In particular, to save space, it only stores primes that are actually necessary to prove the others' primacy. Please post comments and suggestions.
  • 1


#511177 Need help with my char and switch code

Posted by Aereshaa on 27 September 2009 - 08:06 AM

This is an example of a very common error. You shouldn't be using scanf to read input. Just read a whole line in and then use sscanf. You'll get much better results that way.
  • 1


#417721 Makefiles

Posted by Aereshaa on 20 December 2008 - 06:18 PM

The venerable make utility is one of the oldest source control methods that exists. It allows one to compile a program in one shot, without any redundancies, simply by typing:
$ make
The make looks in the current directory for a file named "makefile". The makefile determines which files are dependent on which others. Based on these relations and whether the files have been modified, make executes shell commands found in the makefile.
The basic parts of a makefile are the targets. Targets take the form:
file: dependency dependency dependency
        commands
The commands would produce file from the dependencies. A makefile usually has target rules in order to let the compiler do as little work as possible.
An example would be:
grep : grep.o regex.o
        gcc grep.o regex.o -o grep
grep.o : grep.c
        gcc -c grep.c -o grep.o
regex.o : regex.c
        gcc -c regex.c -o regex.o
In this example, when one modifies regex.c, grep.c is not unnecessarily recompiled. Also, all of the variables in your environment are loaded into make as macros, which are accessed like this: $(CC).
So that's how you use source control with make.
  • 3


#397337 System Time

Posted by Aereshaa on 18 October 2008 - 09:15 PM

Use time() in time.h instead.
  • 1


#394074 Presidential Elections!

Posted by Aereshaa on 11 October 2008 - 09:36 AM

He probably thinks not.
  • 1


#391832 Strings.

Posted by Aereshaa on 07 October 2008 - 05:50 PM

In C, pointers are just about the hardest concept you'll see. A pointer is a simple thing: a variable that stores the location of some data. Assuming you can basically understand pointers, then strings will be a piece of cake. In the instance of a string, the data is a series of characters ending with '\0'. Here's how that looks:
|char * s|
 V
|H|e|l|l|o|\0|
So, unlike languages like Pascal or Java, nowhere in the string is stored its length. Instead, in order to find out a string's length, you call strlen(), from string.h. Here's an implementation of strlen():
[COLOR="Blue"]int[/COLOR] strlen([COLOR="Blue"]char[/COLOR] * s){
 [COLOR="Blue"]int[/COLOR] i = [COLOR="Red"]0[/COLOR];
 [COLOR="Magenta"]while[/COLOR](s[i] != [COLOR="Red"]'\0'[/COLOR])i++;
 [COLOR="Magenta"]return[/COLOR] i;
}
strlen() returns the length of the string, not including the zero byte at the end. This is accomplished by going through it character by character until one reaches the zero byte, at which point the subscript is the length. So, how do you get a string from the user? Well, consider the following program:
[COLOR="Green"]#include "stdio.h"
#include "stdlib.h"
#include "string.h"[/COLOR]
int main(){
 [COLOR="Blue"]char[/COLOR] * str = malloc([COLOR="Red"]100[/COLOR]);
 fgets(str, [COLOR="Red"]100[/COLOR], stdin);
 fputs(str, stdout);
 free(str);
}
Here we introduced several new functions: first, we used malloc(), from stdlib.h. malloc() is used to allocate memory, in other words get space for our string to be in. Here, we allocated 100 bytes of memory, lots of space for a line of input from the user.
Next we call fgets(), which reads a line into a pre-allocated space of memory, from a stream given by the last argument. Because space is limited to what you allocate, fgets() takes a length as an argument, that prevents it from overfilling the array.
After that, we call fputs(), which prints the string to the supplied stream, ending at the zero byte, and free(), which automagically deallocates the right amount of memory.
Here is a piece of code which demonstrates some of the most common mistakes:
[COLOR="Blue"]int[/COLOR] main(){
 [COLOR="Blue"]char[/COLOR] * str = malloc([COLOR="Red"]3000[/COLOR]); //don't allocate huge amounts of memory just for user input! at most, you need 200 bytes per line!
 [COLOR="Magenta"]while[/COLOR](1){
  gets(str); //don't use gets(): it can easily cause pointer errors!
  [COLOR="Blue"]int[/COLOR] i = 0;
  [COLOR="Magenta"]while[/COLOR](i < [COLOR="Red"]3000[/COLOR]){ // that's the end of the allocated region, not the string!
   printf("at %d: \'%c\'",i,str[i]);
  } // i must be incremented!
 } // you didn't free the string! can cause errors later in development!
}

  • 4


#381698 Data Storage in C++ (Visual/ Express Ed.)

Posted by Aereshaa on 13 September 2008 - 06:03 AM

I consider both databases and xml quite bad for data storage in a game. Both require either another big library to link to, or a parser. It's simply much easier to use either flat ascii files, or fwrite(). That way is much faster and does not require any extra libraries.
For example, say you've put the data for an RPG character's stats in a stats structure called playerc:
struct stats * playerc;
FILE * savefile;
//save into file
fwrite(playerc,sizeof(struct stats),1,savefile);
//load saved game
fread(playerc,sizeof(struct stats),1,savefile);

  • 1


#381585 C and UTF-8 support

Posted by Aereshaa on 12 September 2008 - 05:45 PM

I use a jumble of quick hacks, which I've put into functions. Eventually I'll need to sort it out, but an easy hack that I use the most is implementing an & escape like in html. In other words, printf(utf("&3042")); prints "あ".
  • -1


#378403 Aereshaa's Stack-based Calculator.

Posted by Aereshaa on 31 August 2008 - 02:13 PM

TITLE
Aereshaa's Stack-based Calculator.

CHANGE LOG
Sun Aug 31 18:14:58 EDT 2008
First release. Lots of features missing, no error checking.

Issues:
No error checking, therefore misuse of Z or z commands can cause memory leaks or segfaults.
There's no way to put string inside string; will fix this next release.
While loops are shoddy.

LANGUAGE: C
TESTED SYSTEMS: Ubuntu Linux
LICESNSE: Giftware
PRICE: Free


This is a calculator program I've been working on for a bit (like 5 hours over two days). It is fast, and interprets the code on a character, rather than line or word, basis. It uses a simple stack. This code is gift-ware: that is, you are free to do whatever. You may use, modify, redistribute, and generally hack it about in any way you like, and you do not have to give me anything in return. However, questions and comments would be nice!

/*       calcu.c    */
#include "stack.h"
#include "stdio.h"
#include "time.h"
#include "vlstr.h"

#define MD_NORM 'i'
#define MD_CHAR 'c'
#define MD_NPCR 'C'
#define MD_NUMR 'n'
#define MD_XPER 'x'
#define MD_COMM '\\'
#define MD_STRN 's'
#define MD_ESCP 'E'
#define ERR_BADMODE 1
#define ERR_NOCMD 2
int * var;
int * xvar;
int * sta;
int ** s;
char * str;

void execute(int ** st,const char * s);

int interpret(int ** s,const int cmd){
 int ret = 0;
 if(cmd == EOF)ret = 'x';
 if(var[1] == MD_NUMR){
  if(cmd >= '0' && cmd <= '9'){
   int x = cmd - '0';
   int y = st_pop(s);
   x += (y * 10);
   st_push(s,x);
   goto end;
  }else{
   var[1] = xvar[0];
  }
 }
 if(var[1] == MD_NORM){
  if(cmd == 'q')ret = 'x';
  else if(cmd >= '0' && cmd <= '9'){
   int x = cmd - '0';
   st_push(s,x);
   xvar[0] = var[1];
   var[1] = MD_NUMR;
  }
  else if(cmd == '+'){
   int a = st_pop(s);
   int b = st_pop(s);
   st_push(s, a + b);
  }
  else if(cmd == '-'){
   int b = st_pop(s);
   int a = st_pop(s);
   st_push(s, a - b);
  }
  else if(cmd == '*'){
   int a = st_pop(s);
   int b = st_pop(s);
   st_push(s, a * b);
  }
  else if(cmd == '/'){
   int b = st_pop(s);
   int a = st_pop(s);
   st_push(s, a / b);
  }
  else if(cmd == '%'){
   int a = st_pop(s);
   int b = st_pop(s);
   st_push(s, a % b);
  }
  else if(cmd == 'e'){
   int a = st_pop(s);
   int b = st_pop(s);
   st_push(s, a == b);
  }
  else if(cmd == '='){
   int a = st_pop(s);
   int b = st_pop(s);
   var[a] = b;
  }
  else if(cmd == '~'){
   int x = st_pop(s);
   st_push(s,var[x]);
  }
  else if(cmd == 'p'){
   int x = st_top(s);
   printf("%d\n",x);
  }
  else if(cmd == 'Z'){
   str = (char *) st_top(s);
   free(str);
   st_drop(s);
  }
  else if(cmd == 'z'){
   st_drop(s);
  }
  else if(cmd == 'd'){
   int a = st_top(s);
   st_push(s,a);
  }
  else if(cmd == 'f'){
   int a = st_pop(s);
   int b = st_pop(s);
   st_push(s,a);
   st_push(s,b);
  }
  else if(cmd == 'h'){
   if(var[3] == 0)printf("No error occured.\n");
   if(var[3] == ERR_BADMODE)printf("The context was invalid: '%c'\n", xvar[2]);
   if(var[3] == ERR_NOCMD)printf("'%c' is not a valid command.\n", xvar[2]);
   var[3] = 0;
  }
  else if(cmd == '\''){
   xvar[0] = var[1];
   var[1] = MD_CHAR;
  }
  else if(cmd == '{'){
   vl_start(&str);
   xvar[0] = var[1];
   var[1] = MD_STRN;
  }
  else if(cmd == 'P'){
   char * strng = (char *) st_top(s);
   puts(strng);
  }
  else if(cmd == 'x'){
   char * strng = (char *) st_pop(s);
   execute(s,strng);
   st_push(s,(int)strng);
  }
  else if(cmd == 'w'){
   int c = st_pop(s);
   switch(c){
    case 'q':
     puts("q: Quits the interpreter."); break;
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
     puts("0 to 9: Puts that number onto the stack.\nA sequence of numbers like 234 is used to put\nlarger numbers onto the stack."); break;
    case '+':
     puts("+: Performs addition.\nPops two numbers, Pushes their sum."); break;
    case '-':
     puts("-: Performs subtraction.\nA way to show how this works is that\n{21-pz} will print 1."); break;
    case '*':
     puts("*: Performs multiplication.\nPops two numbers, pushes their product."); break;
    case '/':
     puts("/: Performs division.\nThis is inaccurate due to the integer\nnature of the values.\noperand order is the same as subtraction."); break;
    case '%':
     puts("/: Performs modulus.\noperand order is the same as subtraction."); break;
    case '=':
     puts("=: Sets a variable to a value.\n{13'd=} sets variable 'd to 13."); break;
    case 'e':
     puts("e: Equality test.\nPops two numbers, tests their equality,\nand puts 1 on the stack if they are, 0 if not."); break;
    case '~':
     puts("~: Gets the value of a variable.\n{'d~} pushes the value of variable 'd ."); break;
    case 'p':
     puts("p: Prints the number at the top of a stack.\nDoes not pop any numbers.\nUse P for strings."); break;
    case 'd':
     puts("d: Duplicates the number at the top of the stack.\nDo not use on strings, or weird stuff wil happen."); break;
    case 'w':
     puts("w: Prints documentation for a command.\nPops one number (the commmand.)"); break;
    case 'f':
     puts("f: Reverses the order of the two numbers\nat the top of the stack.\nOkay for use on strings."); break;
    case 'h':
     puts("h: Prints an explanation of the last error.\nNot as useful as w."); break;
    case '\'':
     puts("\': Pushes the ascii value of following character."); break;
    case '{':
     puts("{: Begins a string, which continues until the matching }."); break;
    case 'P':
     puts("P: Prints a string.\nDoes not pop anything."); break;
    case 'z':
     puts("z: Pops a number off the stack.\nDo not use on strings, unless\nyou want a memory leak."); break;
    case 'Z':
     puts("Z: Pops a string and frees it.\nDo not use on integers, unless\nyou want a segfault."); break;
    case 'x':
     puts("x: Pops a string, executes it, and pushes it back on."); break;
    default:
     puts("   Either I haven't written documentation for\nthat command, or it doesn't exist."); break;
   }
  }
  else if(cmd == '?'){
   char * strng = (char *) st_pop(s);
   if(var[4])execute(s,strng);
   st_push(s,(int)strng);
  }
  else if(cmd == '@'){
   char * strng = (char *) st_pop(s);
   int a = st_top(s);
   while(var[4])execute(s,strng);
   st_push(s,(int)strng);
  }
  else if(cmd == '\n')xvar[1] = 1;
  else if(cmd == '\\'){
   xvar[0] = var[1];
   var[1] = MD_COMM;
  }
  else if(cmd == ' '); 
  else{
   putchar('?');
   xvar[2] = cmd;
   var[3] = ERR_NOCMD;
  }
  goto end;
 }
 if(var[1] == MD_CHAR){
  st_push(s,cmd);
  var[1] = xvar[0];
  goto end;
 }
 if(var[1] == MD_STRN){
  if(cmd == '}'){
   var[1] = xvar[0];
   xvar[1] = 1;
   st_push(s,(int)str);
  }else{
   vl_add(&str,cmd);
  }
  goto end;
 }
 if(var[1] == MD_COMM){
  if(cmd == '\n'){
   var[1] = xvar[0];
   xvar[1] = 1;
  }
  goto end;
 }
 putchar('?');// Bad Mode? WTF.
 var[3] = ERR_BADMODE;
 xvar[2] = var[1];
 var[1] = MD_NORM;
 end:
 return ret;
}

void execute(int ** st,const char * s){
 int i = 0;
 int len = strlen(s);
 while(i < len){
  interpret(st,s[i]);
  i++;
 }
}

int main(){
 s = &sta;
 st_make(s);
 st_test(s);
 var = malloc(256 * sizeof(int));
 xvar = malloc(16 * sizeof(int));
 var[0] = 256;        // size of var array
 var[1] = MD_NORM;   // interpretation mode
 var[2] = '\\';     // prompt
 var[3] = 0;       // error code
 var[4] = 1;      // conditionals
 xvar[1] = 1;    // for prompting
 int cmd = 0, ret = 0;
 while(ret != 'x'){
  if(var[2] && xvar[1]){
   putchar(var[2]);
   xvar[1] = 0;
  }
  cmd = getchar();
  ret = interpret(s,cmd);
 }
 st_test(s);
 st_dest(s);
}

/*     stack.h   */
#include "stdio.h"
#include "stdlib.h"

#define slen **s
#define stop *(*s + slen * sizeof(int))

void st_make(int ** s){
 *s = malloc(sizeof(int));
 slen = 1;
}

int  st_size(int ** s){
 return slen;
}

void st_push(int ** s, int i){
 *s = realloc(*s,sizeof(int) * (slen + 1));
 slen = slen + 1;
 stop = i;
}

int  st_top (int ** s){
 return stop;
}

void st_drop(int ** s){
 *s = realloc(*s,sizeof(int) * (slen - 1));
 slen = slen - 1;
}

int  st_pop (int ** s){
 int r = st_top(s);
 st_drop(s);
 return r;
}

void st_dest(int ** s){
 free(*s);
}

#undef slen
#undef stop

int st_test(int ** stack){
 st_push(stack, 1234);
 int ret = 1234 == st_top(stack);
 st_drop(stack);
 return ret;
}

/*   vlstr.h    */
#include "string.h"
#include "stdlib.h"

void vl_start(char ** s){
 *s = malloc(1);
 (*s)[0] = 0;
}

void vl_add(char ** s, char c){
 int len = strlen(*s);
 *s = realloc(*s,len + 2);
 (*s)[len] = c;
 (*s)[len + 1] = 0;
}

Attached Files


  • 2


#362870 Allegro Game Library

Posted by Aereshaa on 05 July 2008 - 08:54 PM

It does if you are willing to look up the formulae! For example, I made a 3d Pong game a few weeks ago. Basically, I used Allegro with math.h and checked the formulae on wikipedia. Also there are 3d math routines, although I haven't used them at all...

Okay, so next thing is input. Allegro uses two main sources of input: the keyboard array and the mouse variables. The keyboard array is key[] which is indexed by a kabillion macros: here's how it works:
key[KEY_A]
key[KEY_ESC]
key[KEY_SHIFT]
key[KEY_F1]
key[KEY_CTRL]
...aand so on. A complete list is here.

For mouse, use the variables mouse_x mouse_y, and use the bit-mapped variable mouse_b. mouse_b & 1 is left button, mouse_b & 2 is right, mouse_b & 4 is middle. any other buttons on your mouse can probably be found at later bits.

Okay, next is text. To draw text on the screen, you need a font. Fonts can be loaded to allegro from GRX format .fnt files, 8x8 or 8x16 BIOS format fonts, or from specially prepared bitmaps. Allegro also contains a global font variable, containing a simple font.
To load a font, use the load_font() function, like so.
FONT * myfont = load_font("myfont.fnt",NULL,NULL);
The two NULL arguments are a palette, which doesn't exist, and a loader script file, which is not needed.

So, to use a font, use the textprintf_ex() function.
textprintf(buffer,font,[I]x[/I],[I]y[/I],[I]color[/I],[I]bgcolor[/I],[I]"format string"[/I], ...)
The color or bgcolor arguments may be -1, in which case they are transparent.
There are also textprintf_centre_ex(), and textprintf_right_ex(), variants which treat the coordinates given differently.
  • 2


#362414 Allegro Game Library

Posted by Aereshaa on 02 July 2008 - 10:59 PM

This is a guide to the Allegro Game library, an awesome C library which works on windows, unix, mac OS X, heck, it even works on BeOS and QNX.

Why use the Allegro library and C? Because:
-It is very fast.
-It is under a giftware license.
-...I said so? no? whatever.

So, download allegro here. There will be really helpful information on how to install it inside the package. If you use Dev-C++, there is a devpak. If you use MS Visual Studio.. I dunno. Maybe Xav can figure it out, he uses it.

So once you've got allegro, let's make a simple program using it!
#include the allegro library, allegro.h, and in your main() function, call allegro_init().
Next, if you want to use the mouse or keyboard, call install_keyboard() and/or install_mouse().
Next is graphics. Call set_color_depth(24) (or passing 32, or 16, or 15 or 8), and then call set_gfx_mode(GFX_AUTODETECT_WINDOWED, width, height, 0, 0)
Finally, after the end of your main() function, call END_OF_MAIN().

So, now you should get a blank window which appears for an instant.
To prevent it disappearing until you press the X button, make a global variable called X_button_state, and set it to zero. Make a function called X_button_handler(), inside of which you set X_button_state to one. In main(), call set_close_button_handler(X_button_handler()).

Then, put a loop in the end of your main() function, which doesn't terminate until X_button_state = 1.

Okay, so now I'll tell you about BITMAP structures, blit()ting, and drawing primitives. When you called set_gfx_mode(), you created a BITMAP structure called screen, which is literally the memory mapped pixels of the screen. Writing to the screen, however, is very slow, so it's best to create another BITMAP structure of the same size as your screen, and then, each turn of your main loop, draw to it and then copy the whole thing to the screen.

To do this, outside your main loop, put:
BITMAP * buffer = create_bitmap([I]width[/I],[I]height[/I]);
(Of course, you're free to call it whatever you want.)
Now, inside your loop, at the beginning, clear your buffer to black:
clear_to_color(buffer, 0);
(later, I'll show you how to make other colors)
And at the end, copy it to your screen, using the blit() function, which is for copying large areas of pixels:
blit(buffer,screen,0,0,0,0,[I]width[/I],[I]height[/I]);

So, how do you write to the buffer? Well, let's start with colors. In Allegro, colors are simply int values, which can be generated from rgb colors by calling the makecol() function, as follows:
int red = makecol(255,0,0);
int green = makecol(0,255,0);
int blue = makecol(0,0,255);
For more pretty colors, check out this chart.

Now, let's use a few colors, to draw stuff! There are quite a few primitive drawing functions, so I'll just list them, and their arguments. Test them out, they look cool when moving!
line(buffer,[I]x1[/I],[I]y1[/I],[I]x2[/I],[I]y2[/I],[I]color[/I]); //line
triangle(buffer,[I]x1[/I],[I]y1[/I],[I]x2[/I],[I]y2[/I],[I]x3[/I],[I]y3[/I],[I]color[/I]); //filled triangle
rect(buffer,[I]x1[/I],[I]y1[/I],[I]x2[/I],[I]y2[/I],[I]color[/I]); //rectangle outline
rectfill(buffer,[I]x1[/I],[I]y1[/I],[I]x2[/I],[I]y2[/I],[I]color[/I]); // filled rectangle
circle(buffer,[I]x[/I],[I]y[/I],[I]r[/I],[I]color[/I]); // circle outline
circlefill(buffer,[I]x[/I],[I]y[/I],[I]r[/I],[I]color[/I]); // filled circle
ellipse(buffer,[I]x[/I],[I]y[/I],[I]rx[/I],[I]ry[/I],[I]color[/I]); // ellipse/oval outline
ellipsefill(buffer,[I]x[/I],[I]y[/I],[I]rx[/I],[I]ry[/I],[I]color[/I]); // filled ellipse/oval
... that seems enough for now. see ya later!
  • 3


Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download