Received: from 192.168.151.9
        (SquirrelMail authenticated user chkno)
        by chkno.net with HTTP;
        Sun, 5 Oct 2003 02:27:50 -0700 (PDT)
Message-ID: <42879.192.168.151.9.1065346070.squirrel@chkno.net>
Date: Sun, 5 Oct 2003 02:27:50 -0700 (PDT)
Subject: ltris - expert mode
From: "chkno" <chkno@chkno.net>
To: kulkanie@gmx.net
User-Agent: SquirrelMail/1.4.1
MIME-Version: 1.0
Content-Type: multipart/mixed;boundary="----=_20031005022750_86173"

------=_20031005022750_86173
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 8bit

Attached is a quick-and-dirty patch for an Ltris Expert Mode.  It uses the
AI to weight next-piece probabilities to give you less-than-helpful
pieces, requiring the player to bring their tetris skill to the next level
to continue playing.

Also could be used to tweak the AI by getting some feedback about what it
considers a difficult situation, etc.

The patch contains a TODO where a config variable needs to be pulled in
for enabling/disabling Expert Mode.  I wasn't sure where in the menus
you'd want to put it.  The included patch will turn it on permanently.

(patched against version 1.0.4)


--
chkno
------=_20031005022750_86173
Content-Type: text/x-diff; name="ltris-expert-mode.diff"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="ltris-expert-mode.diff"

diff -ru ltris-1.0.4.orig/src/bowl.c ltris-1.0.4/src/bowl.c
--- ltris-1.0.4.orig/src/bowl.c	2002-07-25 03:49:58.000000000 -0700
+++ ltris-1.0.4/src/bowl.c	2003-10-05 02:03:10.000000000 -0700
@@ -193,6 +193,7 @@
     cpu_analyze_data( &cpu_data );
     bowl->cpu_dest_x = cpu_data.dest_x;
     bowl->cpu_dest_rot = cpu_data.dest_rot;
+    bowl->cpu_dest_score = cpu_data.dest_score;
 }
 /*
 ====================================================================
@@ -202,9 +203,43 @@
 void bowl_create_next_block( Bowl *bowl ) 
 {
     bowl->block.id = bowl->next_block_id;
-    do { 
-        bowl->next_block_id = rand() % BLOCK_COUNT; 
-    } while ( bowl->next_block_id == bowl->block.id );
+    if (1) { /* TODO:  pull in a config option here */
+        /* Weight probability of next block against to helpfulness */
+        int i, j, threshold, saveblockid; 
+        struct { int block, score; } tmp, scores[BLOCK_COUNT];
+
+        saveblockid = bowl->block.id;
+        for (i=0; i<BLOCK_COUNT; i++ ) {
+            bowl->block.id = i;
+            bowl_compute_cpu_dest( bowl );
+            scores[i].block = i;
+            scores[i].score = bowl->cpu_dest_score;
+        }
+        /* Sort */
+        for ( i=0; i<BLOCK_COUNT-1; i++ ) {
+            for ( j=i+1; j<BLOCK_COUNT; j++ ) {
+                if ( scores[j].score < scores[i].score ) {
+                    tmp = scores[i];
+                    scores[i] = scores[j];
+                    scores[j] = tmp;
+                }
+            }
+        }
+        /* 50% chance of worst block, 25% next worse, etc.. */
+        j = rand();
+        threshold = RAND_MAX / 2;
+        for (i=0; i<BLOCK_COUNT-1; i++ ) {
+            if ( j > threshold ) break;
+            threshold /= 2;
+        }
+        bowl->next_block_id = scores[i].block;
+        bowl->block.id = saveblockid;
+    } else {
+        /* Even next-block probabilities */
+        do { 
+            bowl->next_block_id = rand() % BLOCK_COUNT; 
+        } while ( bowl->next_block_id == bowl->block.id );
+    }
     bowl->block.x = 3;
     bowl->block.y = -3;
     bowl->block.sx = bowl->sx + bowl->block_size * bowl->block.x;
diff -ru ltris-1.0.4.orig/src/bowl.h ltris-1.0.4/src/bowl.h
--- ltris-1.0.4.orig/src/bowl.h	2002-06-01 04:49:51.000000000 -0700
+++ ltris-1.0.4/src/bowl.h	2003-10-05 00:54:58.000000000 -0700
@@ -84,6 +84,7 @@
     float preview_alpha_change;
     int cpu_dest_x; /* move block to this position (computed in bowl_create_next_block() */
     int cpu_dest_rot; /* destination rotation */
+    int cpu_dest_score; /* AI score */
     Delay cpu_delay; /* CPU delay before moving down fast */
     Delay cpu_rot_delay; /* rotation delay of CPU */
     int cpu_down; /* move down fast? flag is set when delay expires */
diff -ru ltris-1.0.4.orig/src/cpu.c ltris-1.0.4/src/cpu.c
--- ltris-1.0.4.orig/src/cpu.c	2002-07-25 01:35:01.000000000 -0700
+++ ltris-1.0.4/src/cpu.c	2003-10-05 00:16:51.000000000 -0700
@@ -363,6 +363,7 @@
     cpu_data->dest_x = best_dest->x;
     cpu_data->dest_y = best_dest->y;
     cpu_data->dest_rot = best_dest->rot;
+    cpu_data->dest_score = best_dest->score;
     
     /* DEBUG */
 /*    printf( "DESTINATION: %i/%i\n", best_dest->x, best_dest->rot);
diff -ru ltris-1.0.4.orig/src/cpu.h ltris-1.0.4/src/cpu.h
--- ltris-1.0.4.orig/src/cpu.h	2002-01-11 05:07:14.000000000 -0800
+++ ltris-1.0.4/src/cpu.h	2003-10-05 00:17:42.000000000 -0700
@@ -36,7 +36,7 @@
                                                  and restores by cpu_restore_bowl() */
     int bowl[BOWL_WIDTH][BOWL_HEIGHT]; /* this bowl is used to actually compute stuff */
     Block_Mask *block; /* actual block tested */
-    int dest_x, dest_y, dest_rot; /* this is the CPU result for this data */
+    int dest_x, dest_y, dest_rot, dest_score; /* this is the CPU result for this data */
 } CPU_Data;
 
 /*
------=_20031005022750_86173--



