edition ok

This commit is contained in:
Jérôme Henry-Barnaudière - GeeHB 2023-12-08 12:38:03 +01:00
parent 22c0ae71a8
commit 231557ac09
12 changed files with 513 additions and 33 deletions

View file

@ -8,6 +8,7 @@ find_package(Gint 2.9 REQUIRED)
set(SOURCES
src/sudoSolv.cpp
src/shared/bFile.cpp
src/shared/keyboard.cpp
src/position.cpp
src/element.cpp
src/tinySquare.cpp

View file

@ -9,13 +9,13 @@
#ifndef __S_SOLVER_CONSTANTS_h__
#define __S_SOLVER_CONSTANTS_h__ 1
#include "shared/casioCalcs.h"
#ifdef DEST_CASIO_CALC
#include <gint/display.h>
#include <gint/keyboard.h>
#else
#include <iostream>
#include <cstdint> // <stdint.h>
using namespace std;
#endif //
@ -62,8 +62,8 @@ extern "C" {
// Display
//
#ifdef DEST_CASIO_CALC
#define DELTA_X 3 // Distance from top left corner
#define DELTA_Y DELTA_X // useless in firdt version ....
#define DELTA_X 5 // Distance from top left corner
#define DELTA_Y DELTA_X // useless in first version ....
#define BORDER_THICK 2 // Thickness of external border
@ -73,17 +73,66 @@ extern "C" {
#define GRID_SIZE SQUARE_SIZE * ROW_COUNT
#define BORDER_COLOUR C_RGB(10, 19, 23)
#define OBVIOUS_COLOUR BORDER_COLOUR
#define BK_COLOUR C_RGB(28, 28, 30)
#define TXT_COLOUR C_RGB(8, 8, 8)
#define HILITE_COLOUR C_RGB(30, 15, 14)
#define ORIGINAL_COLOUR C_RGB(30, 15, 14)
#define OBVIOUS_COLOUR BORDER_COLOUR
#define SEL_BK_COLOUR C_RGB(6, 6, 31)
#define SEL_TXT_COLOUR C_WHITE
#endif // #ifdef DEST_CASIO_CALC
// Keyboard
//
// Key codes
//
#ifdef DEST_CASIO_CALC
enum GAME_KEY{
KEY_CODE_F1 = KEY_F1, // !!!
KEY_CODE_F6 = KEY_F6,
KEY_CODE_UP = KEY_UP,
KEY_CODE_DOWN = KEY_DOWN,
KEY_CODE_LEFT = KEY_LEFT,
KEY_CODE_RIGHT = KEY_RIGHT,
KEY_CODE_0 = KEY_0,
KEY_CODE_1 = KEY_1,
KEY_CODE_2 = KEY_2,
KEY_CODE_3 = KEY_3,
KEY_CODE_4 = KEY_4,
KEY_CODE_5 = KEY_5,
KEY_CODE_6 = KEY_6,
KEY_CODE_7 = KEY_7,
KEY_CODE_8 = KEY_8,
KEY_CODE_9 = KEY_9,
KEY_CODE_EXIT = KEY_EXIT,
KEY_CODE_EXE = KEY_EXE
};
#else
enum GAME_KEY{
KEY_CODE_F1 = 'A',
KEY_CODE_F6 = 'F',
KEY_CODE_LEFT = 's',
KEY_CODE_RIGHT = 'f',
KEY_CODE_UP = 'e',
KEY_CODE_DOWN = 'x',
KEY_CODE_0 = '0',
KEY_CODE_1 = '1',
KEY_CODE_2 = '2',
KEY_CODE_3 = '3',
KEY_CODE_4 = '4',
KEY_CODE_5 = '5',
KEY_CODE_6 = '6',
KEY_CODE_7 = '7',
KEY_CODE_8 = '8',
KEY_CODE_9 = '9',
KEY_CODE_EXIT = 'q',
KEY_CODE_EXE = '\13'
};
#endif // #ifdef DEST_CASIO_CALC
#ifdef __cplusplus
}
#endif // #ifdef __cplusplus

View file

@ -15,7 +15,7 @@
// @ status : new status
// @editMode : true if the grid is currentlin edit mode
//
void element::setValue(int value, uint8_t status, bool editMode){
void element::setValue(uint8_t value, uint8_t status, bool editMode){
if (!editMode){
if (!_isStatusBitSet(STATUS_ORIGINAL)){
if (value != EMPTY_VALUE){

View file

@ -23,7 +23,7 @@ extern "C" {
#define STATUS_ORIGINAL 4 // Can't be changed (except in edition mode)
// An empty element value
#define EMPTY_VALUE -1
#define EMPTY_VALUE 0
// element - A single sudoku grid element
//
@ -46,19 +46,21 @@ public:
// @ status : new status
// @editMode : true if the grid is currentlin edit mode
//
void setValue(int value, uint8_t status = STATUS_EMPTY, bool editMode = false);
void setValue(uint8_t value, uint8_t status = STATUS_EMPTY, bool editMode = false);
// Access
//
int value(){
uint8_t value(){
return (_isStatusBitSet(STATUS_SET)?value_:EMPTY_VALUE);
}
// empty() : Empty the element's value
// @return : previous value
int empty(){
uint8_t empty(){
status_ = STATUS_EMPTY;
return value_;
uint8_t value(value_);
value_ = EMPTY_VALUE;
return value;
}
// Element's status
@ -93,7 +95,7 @@ private:
// Members
private:
uint8_t status_;
int value_;
uint8_t value_;
}; // class element
#ifdef __cplusplus

View file

@ -12,7 +12,8 @@
position::position(uint8_t index, bool gameMode){
index_ = index;
status_ = POS_VALID;
status_ = (index <= INDEX_MAX)?POS_VALID:POS_INDEX_ERROR;
gameMode_ = gameMode;
row_ = line_ = 0;
@ -23,7 +24,7 @@ position::position(uint8_t index, bool gameMode){
//
// other : position to copy
//
void position::set(position& other){
void position::set(const position& other){
index_ = other.index_;
status_ = other.status_;
gameMode_ = other.gameMode_;
@ -84,8 +85,9 @@ uint8_t position::backward(uint8_t dec){
// Change "row"
//
void position::decRow(uint8_t dec){
int8_t row = row_ - dec;
index_ = (row < 0)?((1 + line_ ) * ROW_COUNT + row):(index_ - dec);
int8_t row(row_);
row-=dec;
index_ = (row < 0)?(line_ * ROW_COUNT - 1):(index_ - dec);
_whereAmI();
}
@ -137,7 +139,6 @@ uint8_t position::decValue(uint8_t value){
// if false, only square index
//
void position::_whereAmI(bool all){
if (all){
line_ = floor(index_ / ROW_COUNT);
row_ = index_ - ROW_COUNT * line_;

View file

@ -45,12 +45,21 @@ public:
uint8_t status(){
return status_;
}
position& operator=(const position & other){
set(other);
return *this;
}
// set() : Copy a position
//
// other : position to copy
//
void set(position& other);
void set(const position& other);
bool operator!=(const position& other){
return (index_ != other.index_);
}
// moveTo() : Move to an absolute position
//
@ -76,10 +85,16 @@ public:
// Change index
//
// +=
position& operator+=(uint8_t inc){
forward(inc);
return *this;
}
uint8_t forward(uint8_t inc = 1);
// -=
position& operator-=(uint8_t dec){
backward(dec);
return *this;
}
uint8_t backward(uint8_t dec = 1);
// Change "row"

106
src/shared/casioCalcs.h Normal file
View file

@ -0,0 +1,106 @@
//---------------------------------------------------------------------------
//--
//-- File : casioCalcs.h
//--
//-- Author : Jérôme Henry-Barnaudière - GeeHB
//--
//-- Project :
//--
//---------------------------------------------------------------------------
//--
//-- Description:
//--
//-- Types and defines specific to the casio targets
//--
//---------------------------------------------------------------------------
#ifndef __GEE_CASIO_CALCS_h__
#define __GEE_CASIO_CALCS_h__ 1
#ifdef DEST_CASIO_CALC
// Specific includes for calculators
#include <gint/gint.h>
#include <gint/display.h>
// Screen dimensions in pixels
#define CASIO_WIDTH DWIDTH
#define CASIO_HEIGHT DHEIGHT
#else
// Screen dimensions in pixels for tests
#define CASIO_WIDTH 384
#define CASIO_HEIGHT 192
#endif // #ifdef DEST_CASIO_CALC
#include <cstdint>
// A few basic colours
//
#ifndef DEST_CASIO_CALC
// 24 bits RGB (for tests only on Windows and Linux)
#define C_RGB(r,g,b) ((uint32_t)(((uint8_t)(r)|((uint16_t)((uint8_t)(g))<<8))|(((uint32_t)(uint8_t)(b))<<16)))
#endif // #ifndef DEST_CASIO_CALC
#ifdef FX9860G
enum DEF_COLOUR{
COLOUR_BLACK = C_BLACK,
COLOUR_WHITE = C_WHITE,
COLOUR_RED = C_DARK,
COLOUR_GREEN = C_BLACK,
COLOUR_YELLOW = C_BLACK,
COLOUR_BLUE = C_DARK,
COLOUR_LT_BLUE = C_BLACK,
COLOUR_PURPLE = C_DARK,
COLOUR_CYAN = C_BLACK,
COLOUR_ORANGE = C_DARK,
COLOUR_LT_GREY = C_LIGHT,
COLOUR_GREY = C_WHITE,
COLOUR_DK_GREY = C_DARK,
NO_COLOR = -1
};
#else
enum DEF_COLOUR{
COLOUR_BLACK = C_RGB(0, 0, 0),
COLOUR_WHITE = C_RGB(31, 31, 31),
COLOUR_RED = C_RGB(31, 0, 0),
COLOUR_GREEN = C_RGB(0, 31, 0),
COLOUR_YELLOW = C_RGB(31, 31, 0),
COLOUR_BLUE = C_RGB(0, 0, 31),
COLOUR_LT_BLUE = C_RGB(6, 6, 31),
COLOUR_PURPLE = C_RGB(31, 0, 31),
COLOUR_CYAN = C_RGB(0, 31, 31),
COLOUR_ORANGE = C_RGB(31, 16, 0),
COLOUR_LT_GREY = C_RGB(29, 29, 29),
COLOUR_GREY = C_RGB(16, 16, 16),
COLOUR_DK_GREY = C_RGB(8, 8, 8),
NO_COLOR = -1
};
#endif // #ifdef FX9860G
// Point coordinates
//
typedef struct __point {
// Construction
__point(){
x = y = 0;
}
__point(int px, int py){
x = px;
y = py;
}
uint16_t x;
uint16_t y;
} POINT;
// A simple rect. struct
//
typedef struct __rect{
uint16_t x,y; // top left
uint16_t w, h; // width and height
} RECT;
#endif // #ifndef __GEE_CASIO_CALCS_h__
// EOF

72
src/shared/keyboard.cpp Normal file
View file

@ -0,0 +1,72 @@
//---------------------------------------------------------------------------
//--
//-- File : keyboard.cpp
//--
//-- Author : Jérôme Henry-Barnaudière - GeeHB
//--
//-- Project :
//--
//---------------------------------------------------------------------------
//--
//-- Description:
//--
//-- Implementation of keyboard object
//--
//---------------------------------------------------------------------------
#include "keyboard.h"
// Key event in the queue
//
uint keyboard::getKey(){
uint key(KEY_CODE_NONE);
#ifdef DEST_CASIO_CALC
key_event_t evt;
evt = pollevent();
if (evt.type == KEYEV_DOWN){
key = evt.key;
// Modifiers
//
if (key == KEY_SHIFT){
if (!_isSet(MOD_SHIFT)){
_set(MOD_SHIFT);
}
}
else{
if (key == KEY_ALPHA){
if (!_isSet(MOD_ALPHA)){
_set(MOD_ALPHA);
}
}
}
}
else{
if (evt.type == KEYEV_UP){
key = evt.key;
// Modifiers
//
if (key == KEY_SHIFT){
_unSet(MOD_SHIFT);
}
else{
if (key == KEY_ALPHA){
_unSet(MOD_ALPHA);
}
}
}
key = KEY_CODE_NONE;
}
#else
key = getchar();
mod_ = MOD_NONE;
#endif // #ifdef DEST_CASIO_CALC
// return the pressed key code
return key;
}
// EOF

90
src/shared/keyboard.h Normal file
View file

@ -0,0 +1,90 @@
//---------------------------------------------------------------------------
//--
//-- File : keyboard.h
//--
//-- Author : Jérôme Henry-Barnaudière - GeeHB
//--
//-- Project :
//--
//---------------------------------------------------------------------------
//--
//-- Description:
//--
//-- Definition of keyboard object
//--
//---------------------------------------------------------------------------
#ifndef __GEE_TOOLS_KEYBOARD_h__
#define __GEE_TOOLS_KEYBOARD_h__ 1
#include "casioCalcs.h"
#ifdef __cplusplus
extern "C" {
#endif // #ifdef __cplusplus
#ifdef DEST_CASIO_CALC
#include <gint/keyboard.h>
#else
#include <cstdint>
#include <cstdio>
typedef unsigned int uint; // !!!
#endif // #ifdef DEST_CASIO_CALC
#define KEY_CODE_NONE 0
// Type of key modifiers
//
enum MOD_TYPE{
MOD_NONE = 0,
MOD_SHIFT = 1,
MOD_ALPHA = 2
};
// keyboard object - Access to keyboard events
//
class keyboard{
public:
// Construction
keyboard(){
mod_ = MOD_NONE;
}
// Destruction
~keyboard(){}
// Key event in the queue
uint getKey();
// Status of modifiers
bool isPressed(uint mod){
return (mod != MOD_NONE && _isSet(mod));
}
private:
// bitwise ops for modifiers
bool _isSet(uint8_t bit){
return ((mod_& bit) == bit);
}
void _set(uint8_t bit){
mod_ |= bit;
}
void _unSet(uint8_t bit){
mod_ = (mod_ & (~bit));
}
protected:
// Members
uint mod_; // Keyboard modifiers
};
#ifdef __cplusplus
}
#endif // #ifdef __cplusplus
#endif // __GEE_TOOLS_KEYBOARD_h__
// EOF

View file

@ -6,6 +6,7 @@ int main(void)
sudoku myGame;
myGame.display();
myGame.edit(KEY_CODE_EXIT);
getkey();
return 1;

View file

@ -19,6 +19,13 @@ sudoku::sudoku(){
}
empty(); // Start with an empty grid
// basic grid for tests
position pos(0, false);
for (uint8_t i=0; i < 9; i++){
elements_[pos.index()].setValue(i+1, STATUS_ORIGINAL);
pos.forward(10);
}
}
// display() : Display the grid and it's content
@ -50,7 +57,7 @@ void sudoku::display(){
cout << ',';
}
pos.forward(); // next position
pos+=1; // next position
}
}
#endif // #ifdef DEST_CASIO_CALC
@ -94,7 +101,7 @@ uint8_t sudoku::load(FONTCHARACTER fName){
}
if (FILE_SIZE != iFile.read(buffer, FILE_SIZE, 0)){
return SUDO_INVALID_FILESIZE; // Invalid file size
return SUDO_INVALID_FILESIZE;
}
iFile.close();
@ -105,23 +112,22 @@ uint8_t sudoku::load(FONTCHARACTER fName){
char car;
uint8_t value, index(0);
while (index < FILE_SIZE){
// "value"
car = buffer[index++];
car = buffer[index++]; // "value"
if (car >= '0' and car <= '9'){
value = (uint8_t)(car - '0');
if (value && _checkValue(pos, value)){
elements_[pos.index()].setValue(value); // This value is valid at this position
elements_[pos.index()].setValue(value, STATUS_ORIGINAL); // This value is valid at this position and is ORIGINAL
}
}
else{
return false; // Invalid value
return SUDO_INVALID_FORMAT;
}
// separator
car = buffer[index++];
// next element
pos.forward();
pos+=1;
}
// The new grid is valid
@ -151,7 +157,7 @@ uint8_t sudoku::save(FONTCHARACTER fName){
buffer[index++] = pElement->isEmpty()?'0':('0' + pElement->value()); // '0' means empty !
buffer[index++] = VALUE_SEPARATOR;
pos.forward(); // next element
pos+=1; // next element
}
// Replace separator by LF
@ -177,6 +183,115 @@ uint8_t sudoku::save(FONTCHARACTER fName){
return (done?SUDO_NO_ERROR:SUDO_IO_ERROR);
}
#ifdef DEST_CASIO_CALC
// edit() : Edit / modify the current grid
//
// @exitKey : key code of exit key
//
// @return : true if grid has been modified or false if left unchanged
//
bool sudoku::edit(uint exitKey){
bool modified(false);
bool cont(true);
uint car(0);
int8_t val(0);
position currentPos(0, false);
position prevPos(0, false);
keyboard keys;
while (cont){
// if sel. changed, erase previously selected element
if (prevPos != currentPos){
_drawSingleElement(prevPos.row(), prevPos.line(), elements_[prevPos.index()].value(), BK_COLOUR, ORIGINAL_COLOUR);
}
// Hilight the new value
_drawSingleElement(currentPos.row(), currentPos.line(), elements_[currentPos.index()].value(), SEL_BK_COLOUR, SEL_TXT_COLOUR);
dupdate();
prevPos = currentPos;
// Wait for a keyboard event
car = keys.getKey();
switch (car){
// Change the cursor's position
//
case KEY_CODE_LEFT:
currentPos.decRow(); // one row left
break;
case KEY_CODE_RIGHT:
currentPos.incRow(); // one row right
break;
case KEY_CODE_UP:
currentPos.decLine(); // one line up
break;
case KEY_CODE_DOWN:
currentPos.incLine(); // one line down
break;
// Change the current value
//
case KEY_CODE_0:
elements_[currentPos.index()].empty();
modified = true;
break;
case KEY_CODE_1:
modified =_checkAndSet(currentPos, 1);
break;
case KEY_CODE_2:
modified =_checkAndSet(currentPos, 2);
break;
case KEY_CODE_3:
modified =_checkAndSet(currentPos, 3);
break;
case KEY_CODE_4:
modified =_checkAndSet(currentPos, 4);
break;
case KEY_CODE_5:
modified =_checkAndSet(currentPos, 5);
break;
case KEY_CODE_6:
modified =_checkAndSet(currentPos, 6);
break;
case KEY_CODE_7:
modified =_checkAndSet(currentPos, 7);
break;
case KEY_CODE_8:
modified =_checkAndSet(currentPos, 8);
break;
case KEY_CODE_9:
modified =_checkAndSet(currentPos, 1);
break;
case KEY_CODE_EXE:
cont = false;
break;
// ???
default:
break;
} // switch (car)
} // while (cont)
return modified;
}
#endif // #ifdef DEST_CASIO_CALC
//
// Internal methods
//
@ -260,10 +375,10 @@ void sudoku::_drawContent(){
for (row = 0; row < ROW_COUNT; row++){
pElement = &elements_[pos.index()];
if (!pElement->isEmpty()){
_drawSingleElement(row, line, pElement->value(), BK_COLOUR, (pElement->isOriginal()?HILITE_COLOUR:(pElement->isObvious()?OBVIOUS_COLOUR:TXT_COLOUR)));
_drawSingleElement(row, line, pElement->value(), BK_COLOUR, (pElement->isOriginal()?ORIGINAL_COLOUR:(pElement->isObvious()?OBVIOUS_COLOUR:TXT_COLOUR)));
}
pos.forward(); // next element
pos+=1; // next element
}
}
}

View file

@ -17,6 +17,7 @@
#include "tinySquare.h"
#include "shared/bFile.h"
#include "shared/keyboard.h"
#ifdef __cplusplus
extern "C" {
@ -61,6 +62,16 @@ public:
//
uint8_t save(FONTCHARACTER fName);
#ifdef DEST_CASIO_CALC
// edit() : Edit / modify the current grid
//
// @exitKey : key code of exit key
//
// @return : true if grid has been modified or false if left unchanged
//
bool edit(uint exitKey);
#endif // #ifdef DEST_CASIO_CALC
private:
//
@ -70,7 +81,7 @@ private:
// _checkValue() : Can we put the value at the current position ?
//
// @pos : position
// @value : Check thois value at this position
// @value : Check the given value at this 'position'
//
// @return : true if the given value is valid at the given position
//
@ -81,7 +92,7 @@ private:
// _checkLine() : Can we put the value at the current position ?
//
// @pos : position
// @value : Check thois value at this position's line
// @value : Check this value at this position's line
//
// @return : true if the given value is valid in the given line
//
@ -107,6 +118,23 @@ private:
return (false == tSquares_[pos.squareID()].inMe(elements_, value)); // Is the value in the tinySquare ?
}
// _checkAndSet() : Try to put the value at the current position
//
// @pos : position
// @value : value to put
//
// @return : true if value is set
//
bool _checkAndSet(position& pos, uint8_t value){
if (_checkLine(pos, value) && _checkRow(pos, value) && _checkTinySquare(pos, value)){
// set
elements_[pos.index()].setValue(value, STATUS_ORIGINAL, true);
return true;
}
return false;
}
#ifdef DEST_CASIO_CALC
// _drawBorders() : Draw the grid's borders
//