Checkers jump moves (in SFML) - c++

I started coding a few weeks ago and trying out a checker-game right now. I made a class called "figure" and then an array (figure Figure[value]).
I created a 2D field-array in main.cpp and filled it with the numbers for each Figure[]. E.G.:
(main.cpp)
figure Figure[33]; //Figure-array
for (int i = 0; i < 33; i++)
{
Figure[i].id = i;
}
int field[7][7] = { // (I messed the ID's up a little, just ignore it
{0, 0, 1, 2, 3, 0, 0},
{0, 0, 4, 5, 6, 0, 0},
{7, 8, 9, 10, 11, 12, 13}
{14, 15, 16, 17, 18, 19, 20},
{21, 22, 23, 24, 25, 26, 27},
{0, 0, 28, 29, 30, 0, 0},
{0, 0, 31, 32, 33, 0, 0}
};
for (int y = 0; y < 7; y++) //Field gets filled with figure-values {
for (int x = 0; x < 7; x++)
{
if (field[y][x] != 0)
{
Figure[field[y][x] - 1].setPosition(Vector2i(x + 1, y + 1));
}
}
}
Now I want to make an update function to make them jump over each other etc. My problem here is that i dont know is how to do this properly, I dont know how to write this function completely.Here is what i have already:
(Updatefunction)
void figure::update(int (&field)[7][7], RenderWindow &window) {
Vector2i mouseCoords;
mouseCoords.x = int(Mouse::getPosition(window).x / 114);
mouseCoords.y = int(Mouse::getPosition(window).y / 85);
if ((field[mouseCoords.y][mouseCoords.x] != 0) && (Mouse::isButtonPressed(Mouse::Left)))
{
if ((field[mouseCoords.y][mouseCoords.x] != 0) && !(Mouse::isButtonPressed(Mouse::Left)))
{
selected = true; //selected defined in figure.h
}
}
Vector2i newMouseCoords;
newMouseCoords.x = int(Mouse::getPosition(window).x / 114);
newMouseCoords.y = int(Mouse::getPosition(window).y / 85);
if (selected = true)
{
if ((newMouseCoords.x == mouseCoords.x + 2) && (field[newMouseCoords.y][newMouseCoords.x + 2] != 0))
{
}
}
}
I dont know how to continue here, tips are greatly appreciated!

You haven't provided all your code, so I can't give you an exact solution (and your full listing would probably be too long, and make the question unreadable if you included it, so I wouldn't recommend that).
Here's how I would solve it, given what your existing code looks like:
Do something in this function to handle the appropriate turns. Don't let a player move a piece that isn't theirs.
In your first click check, don't just set a non-piece-specific boolean value to true. Store the "selected piece" in some other variable instead.
Before your second click check, see if the "selected piece" variable is set (maybe check if it is not null - depends on how you define that variable).
Inside the body of your second click check, see if the target position for the selected piece constitutes a valid move. If it doesn't, then display an error to the user.
If the second click check constitutes a valid move, then update the board:
Move the piece, capture any pieces it jumped over, king if necessary
If there is another double-jump move that is possible (there might be two double jumps they could choose from), then allow the player to choose another move. This means more "if" blocks...
If there is a double-jump, then allow the person to back out of the move, since they haven't completed it yet. Uncapture their first jump.
Depending on how strict you are being on the rules, don't allow a person to choose not to do a double-jump. Some checkers rules make capture mandatory if it is possible.
Once all moves are complete, then switch the variable that keeps track of whose turn it is, and unset the "selected piece" variable.
Handle the game end check, and the game over state. This probably should be done after a move.

Related

How to assign value to dart enum like in c++

I'm trying to adapt a c++ to dart, and I ran into this situation with enum, assigning default values ​​I think. follow the code
enum skills_t : uint8_t {
SKILL_FIST = 0,
SKILL_CLUB = 1,
SKILL_SWORD = 2,
SKILL_AXE = 3,
SKILL_DISTANCE = 4,
SKILL_SHIELD = 5,
SKILL_FISHING = 6,
SKILL_CRITICAL_HIT_CHANCE = 7,
SKILL_CRITICAL_HIT_DAMAGE = 8,
SKILL_LIFE_LEECH_CHANCE = 9,
SKILL_LIFE_LEECH_AMOUNT = 10,
SKILL_MANA_LEECH_CHANCE = 11,
SKILL_MANA_LEECH_AMOUNT = 12,
SKILL_MAGLEVEL = 13,
SKILL_LEVEL = 14,
SKILL_FIRST = SKILL_FIST,
SKILL_LAST = SKILL_MANA_LEECH_AMOUNT
};
}
uint32_t skillBase[SKILL_LAST + 1] = {50, 50, 50, 50, 30, 100, 20};
Is it possible to adapt this code to dart/flutter?
I would like to replicate the same operation in dart, it seems that he assigned these values ​​to each enum in a range
Yes, it is possible to adapt this code to Dart/Flutter.
In Dart, you can use the enum keyword to define an enumeration. The syntax is similar to C++, but there is no need to specify a type like uint8_t.
Regarding the default values, you can initialize the enum members with a value like in C++.
Here is an example of how the C++ code could be adapted to Dart:
enum Skills {
FIST,
CLUB,
SWORD,
AXE,
DISTANCE,
SHIELD,
FISHING,
CRITICAL_HIT_CHANCE,
CRITICAL_HIT_DAMAGE,
LIFE_LEECH_CHANCE,
LIFE_LEECH_AMOUNT,
MANA_LEECH_CHANCE,
MANA_LEECH_AMOUNT,
MAGLEVEL,
LEVEL,
FIRST = FIST,
LAST = MANA_LEECH_AMOUNT,
}
final List<int> skillBase = [
50, 50, 50, 50, 30, 100, 20
];
You can also use a Map to assign the default values to each enum member.
enum Skills {
FIST,
CLUB,
SWORD,
AXE,
DISTANCE,
SHIELD,
FISHING,
CRITICAL_HIT_CHANCE,
CRITICAL_HIT_DAMAGE,
LIFE_LEECH_CHANCE,
LIFE_LEECH_AMOUNT,
MANA_LEECH_CHANCE,
MANA_LEECH_AMOUNT,
MAGLEVEL,
LEVEL,
FIRST = FIST,
LAST = MANA_LEECH_AMOUNT,
}
final Map<Skills, int> skillBase = {
Skills.FIST: 50,
Skills.CLUB: 50,
Skills.SWORD: 50,
Skills.AXE: 50,
Skills.DISTANCE: 30,
Skills.SHIELD: 100,
Skills.FISHING: 20,
// Add the rest of the skills
};
Both the above examples will work fine in dart/flutter.

C++ Problem filling structs with values from another struct

I'm having an issue trying to figure out why I am not getting the correct functionality with a piece of code. I have looked around to try and find a solution however, I haven't been able to do so. Below is an example of my code:
//Structs
typedef struct
{
int gene[60];
int fitness;
} individual;
typedef struct
{
int cond[5];
int out;
}rule;
//Array of individuals
individual population[P]
int function(individual solution){
int k = 0;
//Array of rules
rule rulebase[10]
for (int i = 0; i < 10; i++){
for (int j = 0; j < 5; j++){
rulebase[i].cond[j] = solution.gene[k++];
}
rulebase[i].out = solution.gene[k++];
}
for (int i = 0; i < 5; i++){
cout << rulebase[0].cond[i];
}
The solution that is passed into the function is the first individual in 'population' and the gene array contains only binary numbers, for example:
gene = [0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1] //There will be 60 in total
The desired functionality is to fill the rule structures in the rulebase with the values found in the solution. For example, using the example above the first rule in the rulebase will have the values below in the 'cond' array:
[0, 0, 1, 0, 1]
and the 'out' will be the next integer in the solution:
[1]
Then the next rule will be filled with the next values in the solution the same way.
The problem that I am having is the code seems to be filling the 'cond' array of each rule with all of the values in the solution, as oppose to the desired way described above. For example, when I print the genes in 'rulebase[0]' I get:
[0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1]
As oppose to:
[0, 0, 1, 0, 1]
I can't seem to figure out why I am getting this problem as the code looks to me like it should work? Any help would be greatly appreciated as I am seriously struggling!
A rule contains only 5 values in cond, not 10 as you show. Its just your code that prints the values of rulebase[0] that is wrong, i.e. it exceeds array bounds and prints - in addition to the cond-values of rulebase[0] - the values of out and cond of the next rule, which - in memory - come next.

Why doesn't my Sudoku program return an output?

So I have tried to implement a Sudoku via backtracking algorithm. I don't see why my code is not giving an expected output.
What I did was, I created a loop in which it checks for an empty cell (represented with 0) in the sudoku. As it finds it, the co-ordinates for it are passed to a function called possibleEntriescheck(). This function writes into a globally declared array called possibleEntries[9], the digits which can be possibly filled into the cell of which the co-ordinates are passed initially.
I learnt this algorithm from these videos:
https://www.youtube.com/watch?v=NuodN41aK3g
https://www.youtube.com/watch?v=QI0diwmx3OY
The expected output is a solved Sudoku. It doesn't perform expectedly. Rather, it freezes. A little help would mean a lot. Thank you.
#include <stdio.h>
#include <stdlib.h>
int board[9][9] = {
{3, 0, 6, 5, 0, 8, 4, 0, 0},
{5, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 8, 7, 0, 0, 0, 0, 3, 1},
{0, 0, 3, 0, 1, 0, 0, 8, 0},
{9, 0, 0, 8, 6, 3, 0, 0, 5},
{0, 5, 0, 0, 9, 0, 6, 0, 0},
{1, 3, 0, 0, 0, 0, 2, 5, 0},
{0, 0, 0, 0, 0, 0, 0, 7, 4},
{0, 0, 5, 2, 0, 6, 3, 0, 0},
};
int possibleEntries[9];
void possibleEntriescheck(int i, int j)
{
int x,a=0,k,l,y;
for(x=0;x<9;x++)
possibleEntries[x]=0;
for(x=0;x<9;x++)
{
if(board[i][x]!=0)
possibleEntries[board[i][x]-1]=1;
}
for(x=0;x<9;x++)
{
if(board[x][j]!=0)
possibleEntries[board[x][j]-1]=1;
}
if(i==0 || i==1 || i==2)
k=0;
else if(i==3 || i==4 || i==5)
k=3;
else
k=6;
if(j==0 || j==1 || j==2)
l=0;
else if(j==3 || j==4 || j==5)
l=3;
else
l=6;
for(x=k;x<k+3;x++)
{
for(y=l;y<l+3;y++)
if(board[x][y]!=0)
possibleEntries[board[x][y]-1]=1;
}
for(x=0;x<9;x++)
{
if(possibleEntries[x]==0)
possibleEntries[x]=x+1;
else
possibleEntries[x]=0;
}
}
int isFull()
{
int i,j;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
if(board[i][j]==0)
return 0;
}
}
return 1;
}
void solveSudoku()
{
int i,j,x,b=0,k;
if(isFull())
{
printf("The sudoku board is:\n");
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
printf("\t%d",board[i][j]);
printf("\n");
}
}
else
{
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
if(board[i][j]==0)
{
possibleEntriescheck(i,j);
for(x=0;x<9;x++)
{
if(possibleEntries[x]!=0)
{
board[i][j]=possibleEntries[x];
solveSudoku();
board[i][j]=0;
}
}
}
}
}
}
return;
}
int main()
{
solveSudoku();
}
You implemented backtracking incorrectly. As also explained in the video, the actual algorithm should look like this:
solve():
if the sudoku is solved
print field
terminate
x,y = the next vacant field
for each possible value in that field
assign value to x,y
call solve() recursively to try with the assigned value
clear vacant field
Now what your code does is
solve():
if the sudoku is solved
print field
return
for each field in the sudoku
if field is vacant
for each possible value
assign value
solve recursively
reset field to unassigned
Now this actually does solve the sudoku. But there are two problems with this approach:
A: It won't terminate once it's solved the sudoku. Actually this mistake was also in the code presented in the video. A simple return in a recursive call will terminate the method on the current call and continue with the recursion "one call above". So basically the algorithm solves the sudoku in every possible way (provided there are multiple, otherwise it simply tries any possible way of assigning the values).
B: This one's way more serious. Your algorithm doesn't only generate all possible solutions, but it also tries every order of assigning the values it can possibly find. The overhead is gigantic and the reason why your code simply doesn't terminate. Solving the sudoku once already takes quite some time, but your code does so a bazillion times.
If you solve these problems, your code should work find, provided the rest is implemented correctly. I'd also recommend optimizing both the search for vacant fields and the test whether the field is empty, as these can be done fairly simple and will provide some speedup. Generate a list of vacant fields in the beginning, iterate over it (one field for each recursion-level) and terminate once the entire list was processed. E.g.:
solve(vacant, count):
if count == 0
print the field
terminate
x, y = vacant[count]
count++
for each possible value assignable to the field
assign value to x, y
call solve(vacant, count) recursively
clear field
Another problem you will encounter, which will get rather ugly to debug is thanks to this line:
int possibleEntries[9];
Global variables that are used and overwritten in a recursion are a bad idea to say the least. Imagine a possible run of the program like this (ident indicates recursion-level, where no ident means the action is global):
solve
|
---> board empty? Nope
x,y <- next vacant field
possible values <- possible values for x, y
field[x, y] <- first value from possible values
solve
|
---> board empty? Nope
x, y <- next vacant field
possible values <- possible values for x, y (overwrites global variable!!!)
field[x, y] <- first value from possible values
solve
|
---> ...
<--- return
field[x, y] <- second value from possible values (WRONG!!!)
...
The last assignment won't use the list of possible values generated for the field you're currently working on, but of another one that you visited somewhere in the recursion before returning back. You can solve this in two ways:
Iterate from 1 to 9 and check for each number separately whether it can be assigned to the field
Keeping a separate list for each level of recursion

How to compare two images by memcmp which one do x-axis flip

I am writing an image processing application in C++ and need to compare images. For example, I have two arrays as below:
int image1[] = {10, 20, 30, 40};
int image2[] = {40, 30, 20, 10};
I would like to find a more efficient way to do comparison than a for loop (like memcmp).
From your question it is not clear if you want to compare two images/int-arrays for equality or if you want to check if one of them is the flipped version of the other.
In any case you should refrain from over-optimizing and using functions like memcmp. From the complexity point of view there is no difference from a for-loop: leave the optimization to your compiler, keep your code easy to read and maintain!
To check if one array is the flipped version of the other, you can use the following code:
int image1[] = {10, 20, 30, 40};
int image2[] = {40, 30, 20, 10};
int len = 4;
bool equal = true;
for (int i = 0; i<len; i++) {
if (image1[i] != image2[len-i-1]) {
equal = false;
break;
}
}
Other thing you can do is to store the image hash along with the image and compare only the image hashes. It has some drawbacks though:
If you use the images for comparison only once, you save no time as hashing requires reading the whole array just as the direct comparison.
Hashing will not 100% guarantee you equality, as there are inherent collisions. Their amount depends on the quality of the hashing function used.
To use hashing for the flipped images, you would also need to generate the hash of a flipped version of the image and use that for comparisons.
You need to get the size from somewhere, then you can memcmp them:
size_t size = 4;
int image1[] = {10, 20, 30, 40};
int image2[] = {40, 30, 20, 10};
if(!memcmp(image1, image2, sizeof(int) * size))
//equal
Mind yourself though, padding might ruin your day in this case.

Not declared in this scope - Arduino

I'm having a problem when I try this code I've made:
int ledStart = 30;
boolean commonHigh = true;
void setup() {
Serial.begin(115200);
SetTimer(0, 0, 10); // 10 seconds
StartTimer();
for (int i =0;i<9;++i) {
pinMode (i, OUTPUT);
}
pinMode(9, INPUT);
}
int counter = 0;
bool go_by_switch = true;
int last_input_value = LOW;
void loop() {
// put your main code here, to run repeatedly:
number++;
delay(1000);
if(number>9)
number=0; // If number is bigger than 9, then number is 0
}
// 0 6
// pins A B C D E F G
int ledpins[] = {12, 10, 7, 4, 2, 13, 8};
int pincnt = 7;
int number = 0;
int sevenseg[10][7] = {
// A, B, C, D, E, F, G
{1, 1, 1, 1, 1, 1, 0}, // A-F shall light. G shall not light.
{0, 1, 1, 0, 0, 0, 0}, // A shall not light. B and C shall light.
/*0*/
/*1*/
/*2*/
/*3*/
/*4*/
/*5*/
/*6*/
/*7*/
/*8*/
{1, 1, 1, 1, 1, 1, 1, 1}
if(go_by_switch) {
int switch_input_value = digitalRead(9);
if(last_input_value == LOW && switch_input_value == HIGH) {
counter = (counter + 1) % 10;
}
last_input_value = switch_input_value;
}
else {
delay(500);
counter = (counter + 1) % 10;
}
writeNumber(counter);
}
for (int p=0; p<pincnt; p++) {
pinMode (ledpins[P], OUTPUT);
//It will count from 0 to smaller than 7. {12, 10, 7, 4, 2, 13, 8}; It will count from 0 to smaller than 7.
// 0 1 2 3 4 5 6
digitalWrite(ledpins[P], LOW);
}
for (int x=0; x<pincnt; x++); { //x is smaller than 7. The point is to bring out one of the patterns that will show on the display
if (sevenseg[number][x]) // sevenseg = 7-segment display
digitalWrite (ledpins[x], HIGH); // If it is 1, then there will be light.
else
digitalWrite (ledpins[x], LOW); // If it is 0, then there will not be light.
// A
//F B
// G
//E C
// D
The error message I get is:
_28.10.2015.ino: In function 'void setup()':
_28.10.2015.ino:7:20: error: 'SetTimer' was not declared in this scope
_28.10.2015.ino:8:14: error: 'StartTimer' was not declared in this scope
_28.10.2015.ino: In function 'void loop()':
_28.10.2015.ino:22:1: error: 'number' was not declared in this scope
_28.10.2015.ino: At global scope:
_28.10.2015.ino:52:1: error: expected '}' before 'if'
_28.10.2015.ino:52:1: error: too many initializers for 'int [7]'
_28.10.2015.ino:52:1: error: expected ',' or ';' before 'if'
Feil ved kompilering.
(Feil ved kompilering=Errors at compile(Norwegian)
The problem is that you are not declaring these functions that you are getting errors, neither the "number" variable.
You need to declare them, like:
int number;
void StartTimer( )
{
// function code;
}
Or include a ".h" that contain these functions, like #Neil Locketz said.
There are quite a few issues with this code.
One of the first things that I notice is that you close out your loop() function with }, then you proceed to write more code that doesn't belong to any function at all.
Also, as #Raul points out, you define an array sevenseg[][], but you do not end the statement with a semicolon.
Your last for() loop is missing its closing brace, }.
Your last for() loop has a semicolon before the opening brace. It shouldn't be there.
You use the variable number in your loop() function, but you define what number is after you use it. You have to define a variable before you use it.
You call SetTimer() and StartTimer() in your setup() function, but those functions are not defined. That's because either 1, you have not included the library where those functions are defined or 2, you did not define those functions yourself. If your issue is 1, then I assume you intended to use #include <SimpleTimer.h>. Note that you also have to install that library. The instructions on how to download it and add it to your Arduino libraries are here. Finally, you have to create a timer object like this: SimpleTimer timer; and then you can call the function like this, timer.SetTimer(your-parameters-here);.
There are probably other things that I have missed, but that should give you a starting point. It looks like you have created a lot of code without testing to see if any of it worked. I would recommend taking this a step at a time... code one logical block and see if it works before you move on to coding your next idea. It may seem like it takes more time but, in the end, it is usually a much faster way to program.
Another suggestion that I would make is to define variables within the function in which you use them. Making all of your variables "global" like you have done is not a good way to write code. For example:
void loop()
{
static int number = 0;
number++;
delay(1000);
if (number > 9)
{
number = 0;
}
}
Note the use of the keyword static. This will ensure that the value stored in number will not go away when the function ends. In other words, the value will still be there the next time the loop() function is called.
Finally, if I had to guess at what you were trying to accomplish, I would think your code should look a little more like this. It appears as though you were trying out different things so I left a number of code snippets in there from your original code that don't actually do anything:
void setup() {
Serial.begin(115200);
for (int i = 0; i < 9; ++i)
{
pinMode (i, OUTPUT);
}
pinMode(9, INPUT);
}
void loop() {
static int counter = 0;
static int last_input_value = LOW;
static bool go_by_switch = true;
if(go_by_switch)
{
int switch_input_value = digitalRead(9);
if(last_input_value == LOW && switch_input_value == HIGH)
{
counter = (counter + 1) % 10;
}
last_input_value = switch_input_value;
}
else
{
delay(500);
counter = (counter + 1) % 10;
}
writeNumber(counter);
}
void writeNumber (int count)
{
#define PIN_COUNT 7
#define NUM_OF_SEGMENTS 7
#define NUM_OF_NUMBERS 10
// 0 6
// pins A B C D E F G
static const int ledpins[PIN_COUNT] = {12, 10, 7, 4, 2, 13, 8};
static const int sevenseg[NUM_OF_NUMBERS][NUM_OF_SEGMENTS] =
{
// A B C D E F G
{1, 1, 1, 1, 1, 1, 0}, //0
{0, 1, 1, 0, 0, 0, 0}, //1
{1, 1, 0, 1, 1, 0, 1}, //2
{1, 1, 1, 1, 0, 0, 1}, //3
{0, 1, 1, 0, 0, 1, 1}, //4
{1, 0, 1, 1, 0, 1, 1}, //5
{1, 0, 1, 1, 1, 1, 1}, //6
{1, 1, 1, 0, 0, 0, 0}, //7
{1, 1, 1, 1, 1, 1, 1}, //8
{1, 1, 1, 1, 0, 1, 1}, //9
};
static int number = 0;
int i;
number++;
delay(1000);
if(number >= NUM_OF_NUMBERS)
{
number = 0;
}
/* Clear all segments of the 7-segment display. */
for (i = 0; i < PIN_COUNT; i++)
{
pinMode (ledpins[i], OUTPUT);
digitalWrite(ledpins[i], LOW);
}
/* Set the 7-segment display with the current number. */
for (i = 0; i < PIN_COUNT; i++)
{
if (sevenseg[number][i]) // sevenseg = 7-segment display
digitalWrite (ledpins[i], HIGH); // If it is 1, then there will be light.
else
digitalWrite (ledpins[i], LOW); // If it is 0, then there will not be light.
}
}