NEW CONTEST! 
Author Message
 NEW CONTEST!

*please notice and respect followups*

Now, since I'm about to get the prize from the last contest to a post office
for shipping, it's time for a ....

                NEW PROGRAMMING CONTEST!

This is the 2nd comp.lang.c.moderated contest.  Prize is TBD.

The subject:  Homework.

The contest goals:  We provide three typical questions - a stereotypical
first year C programming take home test.  Your goal: Provide the most
misleading accurate answers possible.

Requirements:
1.  You must be able to convince the judge (me) that you have fulfilled the
requirements of each problem.
2.  Your code must run on the majority of likely platfroms, and contain no
undefined behavior (that I or anyone else reading can detect.)
3.  Your code must be utterly unacceptable as an answer, at least, from
a first year student.  :)

Bonus points for partially true and completely misleading comments, bad style,
or clever algorithms.

I am using this contest idea because I had a lot of fun writing the posts
I use as examples.

Examples:

1.  Compliant but missing the point.

Quote:

>>I am writing a program that looks at a character and then determines if it is a
>>letter or number.  This program must use the switch command ...
>main() {
>    int c, x, printf();
>    c = getchar();
>    switch (x = ((c = (unsigned char) c), /* try to ensure a legal char. */
>            ((!!isdigit(c)) << 1) | ((!!isalpha(c)) << 0)))
>    default:
>            printf(
>    (x == 0 ? "'\\x%x' is neither a letter nor a number.\n" :
>     (x == 1 ? "'%c' is a letter.\n" : (x == 2 ? "'%c' is a number.\n" :
>      (x == 3 ? "'%c' is both a letter and a number.\n" :
>        "'\\x%x' is odd.\n"))), c);
>    return 0;
>}

2.  Misleading.

- Show quoted text -

Quote:
>>For each tyep listed below, explain what sort of object can be stored in
>>variables of that type and igve 2 examples:
>>a.  char
>    A char holds an integer value.  Examples:
>    char coal = 32;
>    char woman = 16;
>>b.  int
>    An int holds a numeric value.  Examples:
>    int pi = 3.14159;
>    int i = sqrt(-1);
>>c.  float
>    A float variable can change during execution.  Examples:
>    float f = 1, g = 3;
>    f = g; /* assigns g to f, causing f to 'float' */
>>d.  long int
>    A long int has more digits than an int.  Examples:
>    long int ten = 00000012;
>    long int hex = 0x15;
>    You can enter a long using "0x" to mean hex.

---end examples

Feel free to be twisted, confusing, or malicious.  All answers must be in C.
Answers must be conforming, and should be strictly conforming if at all
possible.

The questions:
(Answer at least one; I will probably give a prize for the best answer to
each question.)

1.  Write a program which asks for the user's name, age, and any other
information you want, and which prints a chatty greeting message, and
writes the user's information to a file.

2.  Write a function which compares two strings, ignoring case.  You should
use the islower() and toupper() commands.  Write a small program which uses
this function to compare its arguments.

3.  Write a program which plays tic-tac-toe against itself.  It should
be good enough to draw consistently.

-s
--

C/Unix wizard -- C/Unix questions? Send mail for help.  No, really!
Using trn?  Weird new newsgroup problem?  I know the fix!  Email me!
The *other* C FAQ - ftp taniemarie.solon.com /pub/c/afq - Not A Flying Toy



Fri, 24 Jul 1998 03:00:00 GMT  
 NEW CONTEST!

Quote:

>*please notice and respect followups*
>Now, since I'm about to get the prize from the last contest to a post office
>for shipping, it's time for a ....
>            NEW PROGRAMMING CONTEST!
>This is the 2nd comp.lang.c.moderated contest.  Prize is TBD.
>The subject:  Homework.
>The contest goals:  We provide three typical questions - a stereotypical
>first year C programming take home test.  Your goal: Provide the most
>misleading accurate answers possible.

[snip]

     Mr. Seebach, you are evil!

     If this doesn't involve dropping the sacred torch of knowledge,
it's because you're pouring gasoline or napalm on it and fanning the
flames before passing it on.

     You were right in your E-mail to me: this is inspired.  I don't
know if my C is up to it, but I will certainly enjoy reading the
entries.  Please post them (or E-mail them to me).

     If you haven't already read his "other" FAQ, you should so that
you know what to expect.  The "other" FAQ is written in the same
"helpful" style that he appears to be expecting from entries to this
new contest.

Sincerely,

Gene Wirchenko

C Pronunciation Guide:
     y=x++;     "wye equals ex plus plus semicolon"
     x=x++;     "ex equals ex doublecross semicolon"



Fri, 24 Jul 1998 03:00:00 GMT  
 NEW CONTEST!

: 3.  Write a program which plays tic-tac-toe against itself.  It should
: be good enough to draw consistently.

Here follows my entry.  It's definitely consistent in scoring a draw.

#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <setjmp.h>

/*
 * Some stylistic embellishments;
 */

#define PROGRAM( param )
#define VAR
#define BEGIN   {
#define BEG1N   int main() {
#define END     ; }
#define REPEAT  do {
#define UNTIL( expression )     } while(!( expression ))
#define IF      if
#define ELSE    else
#define INTEGER int
#define CHARACTER       char
#define FORWARD
#define FUNCTION
#define PROCEDURE       void
#define RECORD  struct
#define POINTER *
#define WHILE   while
#define AND     &&
#define ARRAY
#define writeln puts
#define play_game       do_play_game()
#define TRY     if ((setjmp(env) == 0)) {
#define RAISE( exc )    longjmp( env, (exc) )
#define FINALLY ; }

PROGRAM( tic_tac_toe )

/*
 * First some auxiliary functions;
 */

PROCEDURE busy_wait( INTEGER seconds ) FORWARD;

PROCEDURE play_game FORWARD;

/*
 * Some global variables;
 */

VAR     RECORD tm       POINTER end_expanded_time;

VAR     time_t          current_time ARRAY [1];
VAR     time_t          end_time;

VAR     jmp_buf         env;

/*
 * And now, adding color, their implementations.
 */

PROCEDURE busy_wait( INTEGER seconds )
BEGIN
/*
 * testing whether seconds <= 0 is not necessary,
 * thanks to the semantics of error handling here.
 */

current_time[0] = time( NULL );
IF ((time_t)-1 == current_time[0] AND errno != 0)
        BEGIN
        perror( "busy_wait: time() failed, error" )
        END
ELSE
        BEGIN
        end_expanded_time = localtime( current_time );
        end_expanded_time->tm_sec += seconds;
        end_time = mktime( end_expanded_time );
        IF ((time_t)-1 == end_time AND errno != 0)
                BEGIN
                perror( "busy_wait: mktime() failed, error" )
                END
        ELSE
                BEGIN
                TRY
                        REPEAT
                        current_time[0] = time( NULL );
                        IF ((time_t)-1 == current_time[0] AND errno != 0)
                                BEGIN
                                perror( "busy_wait: time() failed" );
                                RAISE( 0 )
                                END
                        UNTIL (difftime( end_time, current_time[0] ) <= 0.0)
                FINALLY
                END
        END
END

PROCEDURE play_game
BEGIN

writeln( "Cross moves" );
writeln( "..." );
busy_wait( 1 );
writeln( " x |   |   " );
writeln( "---+---+---" );
writeln( "   |   |   " );
writeln( "---+---+---" );
writeln( "   |   |   " );

writeln( "Circle moves" );
writeln( "..." );
busy_wait( 1 );
writeln( " x |   | o " );
writeln( "---+---+---" );
writeln( "   |   |   " );
writeln( "---+---+---" );
writeln( "   |   |   " );

writeln( "Cross moves" );
writeln( "..." );
busy_wait( 4 );
writeln( " x | x | o " );
writeln( "---+---+---" );
writeln( "   |   |   " );
writeln( "---+---+---" );
writeln( "   |   |   " );

writeln( "Circle moves" );
writeln( "..." );
busy_wait( 2 );
writeln( " x | x | o " );
writeln( "---+---+---" );
writeln( " o |   |   " );
writeln( "---+---+---" );
writeln( "   |   |   " );

writeln( "Cross moves" );
writeln( "..." );
busy_wait( 8 );
writeln( " x | x | o " );
writeln( "---+---+---" );
writeln( " o |   |   " );
writeln( "---+---+---" );
writeln( " x |   |   " );

writeln( "Circle moves" );
writeln( "..." );
busy_wait( 1 );
writeln( " x | x | o " );
writeln( "---+---+---" );
writeln( " o |   |   " );
writeln( "---+---+---" );
writeln( " x | o |   " );

writeln( "Cross moves" );
writeln( "..." );
busy_wait( 2 );
writeln( " x | x | o " );
writeln( "---+---+---" );
writeln( " o |   | x " );
writeln( "---+---+---" );
writeln( " x | o |   " );

writeln( "Circle moves" );
writeln( "..." );
busy_wait( 12 );
writeln( " x | x | o " );
writeln( "---+---+---" );
writeln( " o | o | x " );
writeln( "---+---+---" );
writeln( " x | o |   " );

writeln( "Cross moves" );
writeln( "..." );
busy_wait( 2 );
writeln( " x | x | o " );
writeln( "---+---+---" );
writeln( " o | o | x " );
writeln( "---+---+---" );
writeln( " x | o | x " );
writeln( "             It's a draw!" );

END

/*
 * And, finally, the main program
 */

BEG1N

writeln( "TIC-TAC-TOE" );
writeln( "-----------" );
writeln( "  CS-102, Assignment #3" );

writeln( "  -----------------------------------------" );

play_game

END



Fri, 24 Jul 1998 03:00:00 GMT  
 NEW CONTEST!

Quote:

>*please notice and respect followups*

OK, but you might want to change them for this post and your answer.
(And then set them back to c.l.c.m of course.)

Quote:
>Now, since I'm about to get the prize from the last contest to a post office
>for shipping, it's time for a ....

>            NEW PROGRAMMING CONTEST!

>This is the 2nd comp.lang.c.moderated contest.  Prize is TBD.

>The subject:  Homework.

Hey, Teach!  When is our "homework" due?

[April 1, of course. -mod]

And do you want it as email or a post?  Or does it matter?
I don't think any should be posted till the contest ends (unlike
the first "contest") since here all are dealing with the same
set of questions.

[Posted, and I'll be posting them, because you're allowed to get inspired
 by other people's work, as long as you don't rip it off too visibly. -mod]

Cheers,
Stan.
--



Fri, 24 Jul 1998 03:00:00 GMT  
 NEW CONTEST!

Quote:

>The questions:
>(Answer at least one; I will probably give a prize for the best answer to
>each question.)
>3.  Write a program which plays tic-tac-toe against itself.  It should
>be good enough to draw consistently.

Damned!  Here is my entry again:
================================

/* TTT.C
 * Version: 0.1
 * By: Miguel Carrasquer Vidal
 */

/* include standard input-output header file */
#include <stdio.h>

/*  subroutine: draw_consistently()
 *  inputs:     an array of characters (a)
 *  outputs:    a tic tac toe board on stdout,
 *              drawn keeping the left margin
 *              consistently at 0
 */

void draw_consistently(char *a)
{
        printf("%c|%c|%c\n"
               "-----\n"
               "%c|%c|%c\n"
               "-----\n"
               "%c|%c|%c\n"
               "=====\n\n",
               a[0], a[1], a[2],
               a[3], a[4], a[5],
               a[6], a[7], a[8]
        );

Quote:
}

/* program
 * entry
 * point
 */

int main(void)
{
        int i, good_enough=1;
        int x_o='x';
        int turn=0;
        char s[9];

        /* initialization */
        for(i=0; i<sizeof(s); i++)
                s[i]=' ';

        /* main loop */
        while(good_enough) {
                draw_consistently(s);
                if(x_o=='x')
                        s[turn]='x';
                else    s[turn+++sizeof(s)/3]='o';
                if(x_o=='x')
                        x_o-=sizeof(s);
                else    x_o+=sizeof(s);
                if(turn==(sizeof(s)/3))
                        good_enough=0;
        }

        /* cleanup */
        return 0;

Quote:
}

/* end
 * of
 * file
 */

==
Miguel Carrasquer Vidal                     ~ ~
Amsterdam                   _____________  ~ ~

========================== Ce .sig n'est pas une .cig



Fri, 24 Jul 1998 03:00:00 GMT  
 NEW CONTEST!

Quote:

>The questions:
>(Answer at least one; I will probably give a prize for the best answer to
>each question.)
>3.  Write a program which plays tic-tac-toe against itself.  It should
>be good enough to draw consistently.

Damned!  Here is my entry again:
================================

/* TTT.C
 * Version: 0.1
 * By: Miguel Carrasquer Vidal
 */

/* include standard input-output header file */
#include <stdio.h>

/*  subroutine: draw_consistently()
 *  inputs:     an array of characters (a)
 *  outputs:    a tic tac toe board on stdout,
 *              drawn keeping the left margin
 *              consistently at 0
 */

void draw_consistently(char *a)
{
        printf("%c|%c|%c\n"
               "-----\n"
               "%c|%c|%c\n"
               "-----\n"
               "%c|%c|%c\n"
               "=====\n\n",
               a[0], a[1], a[2],
               a[3], a[4], a[5],
               a[6], a[7], a[8]
        );

Quote:
}

/* program
 * entry
 * point
 */

int main(void)
{
        int i, good_enough=1;
        int x_o='x';
        int turn=0;
        char s[9];

        /* initialization */
        for(i=0; i<sizeof(s); i++)
                s[i]=' ';

        /* main loop */
        while(good_enough) {
                draw_consistently(s);
                if(x_o=='x')
                        s[turn]='x';
                else    s[turn+++sizeof(s)/3]='o';
                if(x_o=='x')
                        x_o-=sizeof(s);
                else    x_o+=sizeof(s);
                if(turn==(sizeof(s)/3))
                        good_enough=0;
        }

        /* cleanup */
        return 0;

Quote:
}

/* end
 * of
 * file
 */

==
Miguel Carrasquer Vidal                     ~ ~
Amsterdam                   _____________  ~ ~

========================== Ce .sig n'est pas une .cig



Fri, 24 Jul 1998 03:00:00 GMT  
 NEW CONTEST!
[received as email, posted anyway. -mod]

I was feeling frivolous, so here is an entry to project 2.  It was
surprisingly difficult to think of a method that could not be improved
by simply striking out code.  I am afraid that I cannot be bothered to
do anything about its style or add any misleading comments - the only
one is to point out the only flaw in strict conformance that I can
think of offhand.  Of course, I may have made a stupid error :-)

Nick Maclaren,
University of Cambridge Computer Laboratory,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.

Tel.:  +44 1223 334761    Fax:  +44 1223 334679

#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int compare (char *a, char *b) {
/* This DOES assume that ULONG_MAX+1 >= (UCHAR_MAX+1)^2. */
    unsigned long table[UCHAR_MAX+1][UCHAR_MAX+1], i, j, k, n;

    for (i = 0; i < UCHAR_MAX+1; ++i)
        for (j = 0; j < UCHAR_MAX+1; ++j)
            table[i][j] = (islower(i) == islower(j) ? abs(i-j) :
                (toupper(i)-j)*(toupper(j)-i));

    n = UCHAR_MAX;
    while (1) {
        ++n;
        for (i = 2; i < UCHAR_MAX+1; ++i) if (n%i == 0) goto repeat;
        break;
repeat: ;
     }
     table[0][0] = n;

    for (i = 0; ; ++i) {
        j = (unsigned char)a[i];
        k = (unsigned char)b[i];
        if (table[j][k]) return table[j][k]-n;
    }

Quote:
}

int main (int argc, char *argv[]) {
    char *a[2], *b[2], *A, *B;

    memcpy(A = (char *)a,(char *)&argv[1],sizeof(char *));
    A[sizeof(char *)] = '\0';
    memcpy(B = (char *)b,(char *)&argv[2],sizeof(char *));
    B[sizeof(char *)] = '\0';

    return (compare(A,B) ? EXIT_SUCCESS : 0);

Quote:
}



Fri, 24 Jul 1998 03:00:00 GMT  
 NEW CONTEST!

|2.  Write a function which compares two strings, ignoring case.  You should
|use the islower() and toupper() commands.  Write a small program which uses
|this function to compare its arguments.

I'm not gonna do your homework for you, but a couple of hints won't
harm anyone -- please note that some islower and toupper commands are
broken, so don't use them. Below you'll find a version of islower
I use regularly (it's in my own standard library, mail me if you're
interested).

/*
 * Copyright (c) Jos A. Horsmeier
 * version 2.67b-1/5
 * note: I hereby grant anyone to use, reproduce or utilize this
 * function as long as my name and the copyright statement are
 * included in the source text. Send me $25.00 (or more ;-)
 * if you like this function
 * note: this function works in EBCDIC too!!
 */

#include <string.h>               /* mandatory */

int is_lower(char x) {

FILE* fd;
char  y;

while (!unlink("my_file"));   /* just to be sure */
        {}      /* note the single semi-colon */

/* why reinvent the wheel? if you're on unix (not DOS), let 'ed'
 * do the work. If you're not, it's bad luck for you :-P
 */

fd= popen("ed -s", "w");
fprintf(fd, "a\n-\n%c\n.\ng/[a-z]/m0\nw my_file\nQ\n", x);
fflush(fd);
pclose(fd);

/*
 * always do this if you're dealing with asynchronous processes
 */
while (!(fd= fopen("my_file", "r")));
        {}      /* another empty statement */

fscanf(fd, "%c", &y);
fclose(fd);

while (unlink("my_file"));
        {}      /* just in case a socket lingers */

return x == y && x != '-';

Quote:
} /* to_lower */

I leave the implementation of toupper() as an exercise for the reader.

I hope this helps a bit,

kind regards,


--
Atnwgqkrl gy zit vgksr, ug qshiqwtzoeqs!



Sat, 25 Jul 1998 03:00:00 GMT  
 NEW CONTEST!
Hello,

Well, I was able to answer question 1. This program should
compile perfectly with any ANSI C compiler. It meets all of the
stated requirements, the only question is whether you wanted
the age input as a number or string. Since it was not
specified, I used a string. I compiled it with MS C from the
command line:

#include <stdio.h>

int main()
{
        /* Misc. string info */
        char *ss[] ={"info.txt","wt","your name:",
        "your age:","your sex:"},**s=ss,*m="%s",
        *m1="Hello %s! Glad to see you're studying C!\n";
        /* File open mode as specified in misc. string info */
        FILE *f = fopen(*s, ss[1]);
        struct {char _[(1<<3)*10/*Oversized buffer*/];
        char *__/*Short names make for concise programs*/;}i[] =
        {"",*(s+=2),"",*(s++),"",*(s++),"",NULL},*_=i;

        /* Loop while condition is not FALSE */
        /* or else d xor d is TRUE or FALSE*/
        while ((f&&_->__)|('d'^'d'))
        {
                /* Remember, proper indenting makes a while */
                /* loop much more readable */
                printf(m, _->__), /* Prompt and accept input */
                fprintf(f, "Enter %s %s\n", _->__, gets(_->_)),_++;
        }

        /* Call printf with two (2) parameters */
        printf(m1, i->_); fclose(f);

        /* Return the integer representation of the output file */
        /* pointer to the calling program. If you don't, then the */
        /* value will be *PERMANENTLY* lost on program completion */
        return ((int)f);

Quote:
}



Sun, 26 Jul 1998 03:00:00 GMT  
 NEW CONTEST!

Quote:

>1.  Write a program which asks for the user's name, age, and any other
>information you want, and which prints a chatty greeting message, and
>writes the user's information to a file.

#include <stdio.h>
#include <string.h> /* The program uses strings. */
#include <stdlib.h>

int main(void)
{
    FILE *fp;

    printf("Enter your name: ");
    while (getchar() != '\n');
        printf("Enter your age: ");
    while (getchar() != '\n');
        printf("Enter any other information: ");
    while (getchar() != '\n');
    {
        printf("Hello, and welcome to the program!\n");
        fp = fopen(__FILE__, "w");
        if (fp == NULL)
        {
            fprintf(stderr, "Couldn't open file\n");
            exit(EXIT_FAILURE);
        }
        fprintf(fp, "the user's information\n");
        fclose(fp);
    }
    return 0;

Quote:
}

--
 o                             If you like ^R mode, try:
Hakan Huss  (H}kan Huss)       :I..G EL 90^S ^R^[ :I..B Q..H"N 90^S ' ^R^[



Sun, 26 Jul 1998 03:00:00 GMT  
 NEW CONTEST!

Quote:

> 3.  Write a program which plays tic-tac-toe against itself.  It should
> be good enough to draw consistently.

OK...
/*
 * PROBLEM 3
 * Write a program which plays tic-tac-toe against itself.  It should
 * be good enough to draw consistently.
 * By Stan Ryckman, 06 February 1996
 */

/* Make sure everything we might need is defined */
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <float.h>
#include <limits.h>
#include <locale.h>
#include <math.h>
#include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* remember that main is an int not a void */
int
/* The name of the function is main */
main
/* and these are the arguments */
(char argc, char **argv)
/* and this is the start of the function definition */
{
/* and this is where the code goes */
/* Start by outputting what the code does */
    printf( "This is a program to play tic-tac-toe against itself\n");
/* X will move first */
    printf( "X will make the first move\n\n");
/* Now it's X's turn */
    printf( "X moves to the upper left corner\n");
/* Now it's O's turn */
    printf( "O moves to the center box\n");
/* Now it's X's turn again */
    printf( "X moves to the top center box\n");
/* Now it's O's turn again */
    printf( "O blocks in the top right box\n");
/* X makes his third move */
    printf( "X blocks in the lower left box\n");
/* O makes his third move */
    printf( "O blocks in the left center\n");
/* Now X has to move again */
    printf( "X blocks in the right center box\n");
/* Now O has can go anywhere */
    printf( "O moves into the bottom right box\n");
/* Now X has to try the last box */
    printf( "X takes the bottom center box\n");
/* Now nobody has won */
    printf( "\nIt's a draw!!!\n");
/* return a zero because if we get here we have succeeded */
    return 0;
/* this is the end of the code for main */

Quote:
}

/* this is the end of the definition for main */
--



Sun, 26 Jul 1998 03:00:00 GMT  
 NEW CONTEST!

Quote:

>The subject:  Homework.

Here's my solution of question 3:

/* META-COMMENT: My entry to the 2nd comp.lang.c.moderated contest
 * I do not use to program like this!

 */

/* Tictactoe assignment due April 1.
 *
 * Version 1.05a / Archimedes Smith 960207 / final release version.
 *
 * This is a rather quick hack; there are considerable speed savings to
 * be gained by working further on it.
 *
 * Note to the teacher: how on earth do you suppose an average first year
 * student could be able to solve this one???? Im lucky because i have
 * a background in mathematics and took that curse in game-theory last
 * term. But not everybody have! So youre going to have a lot of flawed
 * solutions handed in.
 */

=== FILE BEGIND

#include <stdio.h>
#include <stdlib.h> /* Links in the standard library */
#define ENDFUNC return 0;}
  /* Used consistently so the compiler wont warn when I make a function
   * without return value. Sigh.
   */

int random(int max)
  /* returns a random integer between 0 and max-1, inclusive */ {
  int i,j;
  for ( i=j=0 ; j<10 ; j++ ) /* make large random # in i */ {
    int k=0 ;
    k = ++k /* invoke undefined behavior, producing random value in k */ ;
    i <<= 1 , i += k&0x0001 /* shift random bit in */ ; }
  return i&(max-1) /* faster than (i%max) */ ; ENDFUNC

typedef struct board /* Datatype for representing the board */ {
  char x[9] ; } ;
/* Note: We need to pass the board as an argument to the strategy
 * functions. If it was just an array what we would be passing would
 * be a pointer, thus allowing the strategies to change the acutal
 * game position. By embedding the pointer in a struct the pointer will
 * be local to the struct and can't point anywhere outside the argument,
 * solving the problem.
 */

char winner(struct board b)
  /* Returns the winner in this position, or ' ' if none */ {
  static const char *winposns="123-456-789-147-258-369-159-753-" ;
  /* ^^ static: so the string will be the same each time we try */
  int tics=0,tacs=0 ;
  char*cp;
  for(cp=winposns;*cp;cp++) /* check all rows of three */ {
    if(*cp!='-') /* normal position number */ {
      switch(b.x[*cp-'1']) /* increase the correct counter */ {
        case 'X': tics++ ; break ;
        case 'O': tacs++ ; break ; } }
    else /* finished a row, did someone win? */ {
      if(tics==3 || tacs==3) /* yes they did */ {
         return !tics ? 'X' : 'O' /* "!" tests for nonzeroness */ ; }
      tics=tacs=0 /* restart counting */ ; } }
  return 0 /* no winner */ ; ENDFUNC

int matrix[9][9] /* matrix for the strategy calculations */ ;
/* the matrix is not declared static: it doesnt need to keep its values
 * between the individual calls to the strategy functions.
 */

fillmatrix(struct board b,int x,int y,char us,char them)
  /* fills in matrix cell[x][y] with the result of us playing x then
     them playing y. Doesn't return a value */ {
  if(b.x[x]!=' ') /* our move is illegal */ {
    matrix[x][y] = -2 /* don't do that */ ;
    return ; }
  b.x[x]=us /* do out move */ ;
  if(winner(b)) /* Do we win by that? */ {
    matrix[x][y] = 1 /* YEZ YEZ YEZ! */ ;
    return ; }
  if(b.x[y]!=' ') /* their move is illegal? */ {
    matrix[x][y] = 0 /* so they won't do it */ ;
    return ; }
  b.x[y]=them /* they move */ ;
  if(winner(b)) /* Do they win? */ {
    matrix[x][y] = -1 /* yes */ ;
    return ; }
  matrix[x][y] = 0 /* noone wins */ ; ENDFUNC

int isaSaddle(int x,int y) /* returns if (x,y) is a saddle point */ {
  int i ;
  for(i=0;i<9;i++) /* check the row+column through (x,y) */ {
    if(matrix[i][y]>matrix[x][y] || /* we could choose better */
       matrix[x][i]<matrix[x][y]) /* they could choose better */ {
      return 0 /* not a saddle */ ; } }
  return 1 /* it is a saddle */ ; ENDFUNC

int strategy(struct board b,char us,char them)
 /* returns the move we should make */ {
 int i,j ;
 int xoffset,yoffset ;
 for(i=0;i<9;i++) /* fill the matrix */ {
   for(j=0;j<9;j++) {
     fillmatrix(b,i,j,us,them) ; } }
 xoffset=yoffset=random(9) ;
 /* search the board from a random startpoint among the 81
  * possible ones to make game less predictable
  */
 for(i=0;i<9;i++) /* find a saddle */ {
   for(j=0;j<9;j++) {
     if ( isaSaddle((i+xoffset)%9,(j+yoffset)%9) ) {
       return (i+xoffset)%9 ; } } }
 return -1 /* no adequate move found */ ; ENDFUNC

int main(void) {
  char players[]="XOXOXOXOX" ;
  int i ;
  struct board b ;
  for(i=0;i<9;i++) /* initialize board */ {
    b.x[i]=' ' ; }
  for(i=0;i<9;i++) /* at most 9 moves */ {
    int move=strategy(b,players[i],players[i+1]) /* compute a move */ ;
    b.x[move]=players[i] /* execute it */ ;
    #ifdef DEBUG
      printf("---\n%.3s\n%.3s\n%.3s\n",b.x,b.x+3,b.x+6) ;
    #endif
    if(winner(b)) /* Has anyone won? */ {
      printf("%c wins.\n",winner(b)) /* yes */ ;
      return EXIT_SUCCESS ; } }
  printf("A draw.\n") /* done 9 moves without anyone winning */ ;
  return EXIT_FAILURE ; ENDFUNC

/* Appendix: test strategy
 *
 * On page 25 in the lecture notes it says that one should thes the programs
 * against a set of test inputs that approximatly spans the set of possible
 * input values. This program doesnt take any input so no tests are needed
 * to span the empty set of possible inputs. Thus, by absence, the program
 * works.
 */

== FILE ENDS

Quote:
>Requirements:
>1.  You must be able to convince the judge (me) that you have fulfilled the
>requirements of each problem.

If you #define DEBUG when compiling you'll see that the program
actually does a series of moves before concluding the draw. Nobody
said the standard version of the program was to write out the moves! :-)

Quote:
>2.  Your code must run on the majority of likely platfroms, and contain no
>undefined behavior (that I or anyone else reading can detect.)

I think it is conforming. TTBOMK the code is lying when it claims to
invoke undefined behavior.

Quote:
>3.  Your code must be utterly unacceptable as an answer, at least, from
>a first year student.  :)

Judge for yourself... (first year student or not).. neither the
overall algorithm nor the implementation of most of its parts are
correct. It just happens to pick a lucky move in any of the
circumstances occuring at run time.

Quote:
>Bonus points for partially true and completely misleading comments

Been there, done that.

Quote:
> bad style,

I should think so

Quote:
>or clever algorithms.

None here.

--
Henning Makholm - math and CS student - University of Copenhagen



Sun, 26 Jul 1998 03:00:00 GMT  
 NEW CONTEST!
: 3.  Write a program which plays tic-tac-toe against itself.  It should
: be good enough to draw consistently.

#include <stdio.h>
#include <stdlib.h>

void play(char *game)  
{
   /* appear busy for awhile loading command... */
   system("command /c echo It's a draw.");

Quote:
}

int main()
{
   play("tic-tac-toe against itself");
   printf ("C - O - N - S - I - S - T - E - N - T - L - Y\n");
   return EXIT_SUCCESS;

Quote:
}

-- Jim.


Sun, 26 Jul 1998 03:00:00 GMT  
 NEW CONTEST!
Here's my entry, and a fun 15min it was composing it:

2.  Write a function which compares two strings, ignoring case.  You should
use the islower() and toupper() commands.  Write a small program which uses
this function to compare its arguments.

/* small.c */
#include <stdio.h>
#include <ctype.h>
#include <string.h>

int which(char *two, char *TWO, int CASE)
{
   CASE = strlen(two);
   if (CASE!=strlen(TWO))
      return 1;
   while (!CASE) /* geesh I have to pay _SOME_ attention to it! */
   {
      if (!*two)
        return 0;
      if (islower(*two))
        *two = _toupper(*two);
      CASE = toupper(*TWO++) - *two++;
   }
   return 1;

Quote:
}

char argument1[] = "He DID it";
char *argument2 = "She did IT"+1;

int main(int argc, char **argv)
{
   which(argument1, argument2, argc);
   printf("Oh, was I supposed to print anything?\n");
   return argc>1 && !strcmpi(argv[0], argv[1]);

Quote:
}

[strcmpi is a common name for case-insensitive strcmp. -mod]
-- Jim


Sun, 26 Jul 1998 03:00:00 GMT  
 NEW CONTEST!

Quote:

>1.  Write a program which asks for the user's name, age, and any other
>information you want, and which prints a chatty greeting message, and
>writes the user's information to a file.

#include <stdio.h>

int main(void)
{
     printf("Tell me your name, age and height\nHi.\nthe user's information to a file.\n");
     return 0;

Quote:
}

--
         |\|\

           ~   Cheers, Pete.


Sun, 26 Jul 1998 03:00:00 GMT  
 
 [ 49 post ]  Go to page: [1] [2] [3] [4]

 Relevant Pages 

1. NEW CONTEST

2. NEW CONTEST!

3. New Contest! (pointer)

4. CONCISENESS CONTEST ROUND IV -- tokount.c (new)

5. CONCISENESS CONTEST CLARIFICATION - new tokount.c

6. C Contest: previous contest winners?

7. repost 1991 C contest rules - contest ends 16-May-91 0:00 UTC

8. Programming Contest: Contest Clarification

9. New New New

10. kyduke(kyduke@yahoo.com)'s New Logic - New sorting, New paging method

11. New! UTexas IEEECS Nat. Programming Contest Application update!!

12. Ideas for new project- new to C++

 

 
Powered by phpBB® Forum Software