1414#define RIGHT 4
1515
1616// Precomputed constants
17- #define REWARD_MULTIPLIER 0.09090909f
17+ #define REWARD_MULTIPLIER 0.0625f
1818#define INVALID_MOVE_PENALTY -0.05f
1919#define GAME_OVER_PENALTY -1.0f
2020
@@ -93,9 +93,24 @@ static inline void update_empty_count(Game* game) {
9393 game -> empty_count = count ;
9494}
9595
96+ // Optimized score calculation
97+ static inline unsigned char calc_score (Game * game ) {
98+ unsigned char max_tile = 0 ;
99+ // Unroll loop for better performance
100+ for (int i = 0 ; i < SIZE ; i ++ ) {
101+ for (int j = 0 ; j < SIZE ; j ++ ) {
102+ if (game -> grid [i ][j ] > max_tile ) {
103+ max_tile = game -> grid [i ][j ];
104+ }
105+ }
106+ }
107+ return max_tile ;
108+ }
109+
96110void add_log (Game * game ) {
97- game -> log .score = (float )(1 << game -> score );
98- game -> log .perf += ((float )game -> score ) * REWARD_MULTIPLIER ;
111+ unsigned char s = calc_score (game );
112+ game -> log .score = (float )(1 << s );
113+ game -> log .perf += ((float )s ) * 0.0909f ;
99114 game -> log .episode_length += game -> tick ;
100115 game -> log .episode_return += game -> episode_reward ;
101116 game -> log .n += 1 ;
@@ -162,7 +177,7 @@ void add_random_tile(Game* game) {
162177}
163178
164179// Optimized slide and merge with fewer memory operations
165- static inline bool slide_and_merge (unsigned char * row , float * reward ) {
180+ static inline bool slide_and_merge (unsigned char * row , float * reward , float * score_increase ) {
166181 bool moved = false;
167182 int write_pos = 0 ;
168183
@@ -183,6 +198,7 @@ static inline bool slide_and_merge(unsigned char* row, float* reward) {
183198 if (row [i ] != EMPTY && row [i ] == row [i + 1 ]) {
184199 row [i ]++ ;
185200 * reward += ((float )row [i ]) * REWARD_MULTIPLIER ;
201+ * score_increase += (float )(1 << (int )row [i ]);
186202 // Shift remaining elements left
187203 for (int j = i + 1 ; j < SIZE - 1 ; j ++ ) {
188204 row [j ] = row [j + 1 ];
@@ -195,7 +211,7 @@ static inline bool slide_and_merge(unsigned char* row, float* reward) {
195211 return moved ;
196212}
197213
198- bool move (Game * game , int direction , float * reward ) {
214+ bool move (Game * game , int direction , float * reward , float * score_increase ) {
199215 bool moved = false;
200216 unsigned char temp [SIZE ];
201217
@@ -207,7 +223,7 @@ bool move(Game* game, int direction, float* reward) {
207223 temp [i ] = game -> grid [idx ][col ];
208224 }
209225
210- if (slide_and_merge (temp , reward )) {
226+ if (slide_and_merge (temp , reward , score_increase )) {
211227 moved = true;
212228 // Write back column
213229 for (int i = 0 ; i < SIZE ; i ++ ) {
@@ -224,7 +240,7 @@ bool move(Game* game, int direction, float* reward) {
224240 temp [i ] = game -> grid [row ][idx ];
225241 }
226242
227- if (slide_and_merge (temp , reward )) {
243+ if (slide_and_merge (temp , reward , score_increase )) {
228244 moved = true;
229245 // Write back row
230246 for (int i = 0 ; i < SIZE ; i ++ ) {
@@ -280,28 +296,15 @@ bool is_game_over(Game* game) {
280296 return true;
281297}
282298
283- // Optimized score calculation
284- static inline unsigned char calc_score (Game * game ) {
285- unsigned char max_tile = 0 ;
286- // Unroll loop for better performance
287- for (int i = 0 ; i < SIZE ; i ++ ) {
288- for (int j = 0 ; j < SIZE ; j ++ ) {
289- if (game -> grid [i ][j ] > max_tile ) {
290- max_tile = game -> grid [i ][j ];
291- }
292- }
293- }
294- return max_tile ;
295- }
296-
297299void c_step (Game * game ) {
298300 float reward = 0.0f ;
299- bool did_move = move (game , game -> actions [0 ] + 1 , & reward );
301+ float score_add = 0.0f ;
302+ bool did_move = move (game , game -> actions [0 ] + 1 , & reward , & score_add );
300303 game -> tick ++ ;
301304
302305 if (did_move ) {
303306 add_random_tile (game );
304- game -> score = calc_score ( game ) ;
307+ game -> score += score_add ;
305308 update_empty_count (game ); // Update after adding tile
306309 }
307310
@@ -369,7 +372,7 @@ void c_render(Game* game) {
369372 }
370373
371374 // Draw score (format once per frame)
372- snprintf (score_text , sizeof (score_text ), "Score: %d" , 1 << game -> score );
375+ snprintf (score_text , sizeof (score_text ), "Score: %d" , game -> score );
373376 DrawText (score_text , 10 , px * SIZE + 10 , 24 , PUFF_WHITE );
374377
375378 EndDrawing ();
0 commit comments