I have the raw color data for four images, let's call them 1, 2, 3, and 4. I am storing the data in an unsigned char * with allocated memory. Individually I can manipulate or encode the images but when trying to concatenate or order them into a single image it works but takes more time than I would like.
I would like to create a 2 by 2 of the raw image data to encode as a single image.
1 2
3 4
For my example each image is 400 by 225 with RGBA (360000 bytes). Iim doing a for loop with memcpy where
for (int j = 0; j < 225; j++)
{
std::memcpy(dest + (j * (400 + 400) * 4), src + (j * 400 * 4), 400 * 4); //
}
for each image with an offset for the starting position added in (the example above would only work for the top left of course).
This works but I'm wondering if this is a solved problem with a better solution, either in an algorithm described somewhere or a small library.
#include <iostream>
const int width = 6;
const int height = 4;
constexpr int n = width * height;
int main()
{
unsigned char a[n], b[n], c[n], d[n];
unsigned char dst[n * 4];
int i = 0, j = 0;
/* init data */
for (; i < n; i++) {
a[i] = 'a';
b[i] = 'b';
c[i] = 'c';
d[i] = 'd';
}
/* re-order */
i = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++, i++, j++) {
dst[i ] = a[j];
dst[i + width] = b[j];
dst[i + n * 2 ] = c[j];
dst[i + n * 2 + width] = d[j];
}
i += width;
}
/* print result */
i = 0;
for (int y = 0; y < height * 2; y++) {
for (int x = 0; x < width * 2; x++, i++)
std::cout << dst[i];
std::cout << '\n';
}
return 0;
}
With the implementation below, based on the pseudo-code available here, I am trying to convert a string generated with the concatenation of the members from this class:
class BlockHeader
{
private:
int version;
string hashPrevBlock;
string hashMerkleRoot;
int time;
int bits;
int nonce;
}
into a SHA256 hash, like what was done with the python code below, available here:
>>> import hashlib
>>> header_hex = ("01000000" +
"81cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000" +
"e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122b" +
"c7f5d74d" +
"f2b9441a" +
"42a14695")
>>> header_bin = header_hex.decode('hex')
>>> hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()
>>> hash.encode('hex_codec')
'1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e0000000000000000'
>>> hash[::-1].encode('hex_codec')
'00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d'
I expect that my program would return the same result the program above returned, but instead, when I compile and run this:
int main() {
BlockHeader header;
header.setVersion(0x01000000);
header.setHashPrevBlock("81cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000");
header.setHashMerkleRoot("e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122b");
header.setTime(0xc7f5d74d);
header.setBits(0xf2b9441a);
header.setNonce(0x42a14695);
Sha256 hash1(header.bytes());
array<BYTE, SHA256_BLOCK_SIZE> h1 = hash1.hash();
cout << "hash1: ";
for(int i=0; i<h1.size(); i++)
printf("%.2x", h1[i]);
printf("\n");
Sha256 hash2(h1);
array<BYTE, SHA256_BLOCK_SIZE> h2 = hash2.hash();
cout << "hash2: ";
for(int i=0; i<h2.size(); i++)
printf("%.2x", h2[i]);
printf("\n");
}
the result is that:
hash1: e2245204380a75c6bc6ac56f0000000040030901000000001100011000000000
hash2: 68a74f2a36c8906068c6cd6f00000000020000000000000080a7d06f00000000
I am aware the endianess in my program are not the same of the python result, but this I can fix later, when I get the correct result. Looking in the code below, can anyone give a hint of what I am missing here?
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
Sha256::Sha256(vector<BYTE> data) {
SIZE64 L = data.size() / 2;
SIZE64 K = 0;
while( (L + 1 + K + 8) % 64 != 0)
K = K + 1;
for(int i=0; i<L; i++) {
BYTE c = (data[i] % 32 + 9) % 25 * 16 + (data[i+1] % 32 + 9) % 25;
source.push_back(c);
}
source.push_back(0x80);
for(int i=0; i<K; i++)
source.push_back(0x00);
SIZE64 x = L + 1 + K + 8;
for(int i=0; i<sizeof(x); i++)
source.push_back( x >> i*8 );
}
Sha256::Sha256(array<BYTE, SHA256_BLOCK_SIZE> data) {
SIZE64 L = data.size() / 2;
SIZE64 K = 0;
while( (L + 1 + K + 8) % 64 != 0)
K = K + 1;
for(int i=0; i<L; i++) {
BYTE c = (data[i] % 32 + 9) % 25 * 16 + (data[i+1] % 32 + 9) % 25;
source.push_back(c);
}
source.push_back(0x80);
for(int i=0; i<K; i++)
source.push_back(0x00);
SIZE64 x = L + 1 + K + 8;
for(int i=0; i<sizeof(x); i++)
source.push_back( x >> i*8 );
}
array<BYTE, SHA256_BLOCK_SIZE> Sha256::hash() {
array<BYTE, SHA256_BLOCK_SIZE> result;
WORD32 h0 = 0x6a09e667, h1 = 0xbb67ae85, h2 = 0x3c6ef372, h3 = 0xa54ff53a, h4 = 0x510e527f, h5 = 0x9b05688c, h6 = 0x1f83d9ab, h7 = 0x5be0cd19;
WORD32 k[64] = {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
WORD32 a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
for(int chunk=0; chunk<=source.size()/64; chunk++) {
for (i = 0, j = chunk*64; i < 16; ++i, j += 4)
m[i] = (source[j] << 24) | (source[j + 1] << 16) | (source[j + 2] << 8) | (source[j + 3]);
for ( ; i < 64; ++i)
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
a = h0;
b = h1;
c = h2;
d = h3;
e = h4;
f = h5;
g = h6;
h = h7;
for (i = 0; i < 64; ++i) {
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
t2 = EP0(a) + MAJ(a,b,c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
h0 += a;
h1 += b;
h2 += c;
h3 += d;
h4 += e;
h5 += f;
h6 += g;
h7 += h;
}
for(int i=0; i<4; i++) result[0] = h0 >> i;
for(int i=0; i<4; i++) result[1] = h1 >> i;
for(int i=0; i<4; i++) result[2] = h2 >> i;
for(int i=0; i<4; i++) result[3] = h3 >> i;
for(int i=0; i<4; i++) result[4] = h4 >> i;
for(int i=0; i<4; i++) result[5] = h5 >> i;
for(int i=0; i<4; i++) result[6] = h6 >> i;
for(int i=0; i<4; i++) result[7] = h7 >> i;
return result;
}
In the Sha256::hash function, result is a BYTE array, whereas h0 is a WORD32. You might want to split h0 into 4 BYTEs and store into the result array, but the for loop at the end of the function won't achieve your goal.
What you want to do is to concatenate h0 to h7, and then extract the bytes from h0 to h7 by shifting 24, 16, 8, 0 bits:
// concatenate h0 to h7
WORD32 hs[8] = {h0, h1, h2, h3, h4, h5, h6, h7};
// extract bytes from hs to result
for(int i=0; i<8; i++) { // loop from h0 to h7
result[i*4 ] = hs[i] >> 24; // the most significant byte of h_i
result[i*4+1] = hs[i] >> 16;
result[i*4+2] = hs[i] >> 8;
result[i*4+3] = hs[i]; // the least significant byte of h_i
}
EDIT
After some testing, I found another error:
for(int chunk=0; chunk<=source.size()/64; chunk++) {
^^
should be
for(int chunk=0; chunk<source.size()/64; chunk++) {
^
chuck starts from 0, so you should use < instead of <=.
For example, when source.size() is 64, you only have 1 chunk to process.
EDIT2
I fully tested your code and found two problems in the constructors of the Sha256 class.
Your code implies that you assume the vector<BYTE> passed to the constructor is a hex string. That is OK, but you use the same code for the array<BYTE, SHA256_BLOCK_SIZE> version, which is the return type of hash() function, which returns a BYTE array instead of hex string.
For a BYTE array, you can simply push the byte data[i] into the source. Also, L should be data.size() because every element has size 1 in a byte array.
Besides, you try to append the size of the input(x) to source, but x should not include the appended one and zeros, and it is the bit count of the input, so x should simply be L*8. Also, the size should be a big-endian integer, so you have to push the bigger byte first:
for(int i=0; i<sizeof(x); i++) // WRONG: little endian
for(int i=sizeof(SIZE64)-1; i>=0; i--) // Correct: big endian
I have made it execute correctly and output:
hash1: b9d751533593ac10cdfb7b8e03cad8babc67d8eaeac0a3699b82857dacac9390
hash2: 1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e0000000000000000
If you encounter other problems, feel free to ask. You are very close to the correct answer. Hope you can fix all the bugs successfully :)
EDIT3: implementation of other function
struct BlockHeader {
int version;
string hashPrevBlock;
string hashMerkleRoot;
int time;
int bits;
int nonce;
vector<BYTE> bytes();
};
#define c2x(x) (x>='A' && x<='F' ? (x-'A'+10) : x>='a' && x<='f' ? (x-'a'+10) : x-'0')
vector<BYTE> BlockHeader::bytes() {
vector<BYTE> bytes;
for (int i=24; i>=0; i-=8) bytes.push_back(version>>i);
for (int i=0; i<hashPrevBlock.size(); i+=2)
bytes.push_back(c2x(hashPrevBlock[i])<<4 | c2x(hashPrevBlock[i+1]));
for (int i=0; i<hashMerkleRoot.size(); i+=2)
bytes.push_back(c2x(hashMerkleRoot[i])<<4 | c2x(hashMerkleRoot[i+1]));
for (int i=24; i>=0; i-=8) bytes.push_back(time>>i);
for (int i=24; i>=0; i-=8) bytes.push_back(bits>>i);
for (int i=24; i>=0; i-=8) bytes.push_back(nonce>>i);
return bytes; // return bytes instead of hex string
}
// exactly the same as the vector<BYTE> version
Sha256::Sha256(array<BYTE, SHA256_BLOCK_SIZE> data) {
SIZE64 L = data.size(); // <<
SIZE64 K = 0;
while( (L + 1 + K + 8) % 64 != 0)
K = K + 1;
// can be simplified to: int K = (128-1-8-L%64)%64;
// ** thanks to "chux - Reinstate Monica" pointing out i should be a SIZE64
for(SIZE64 i=0; i<L; i++) { // **
source.push_back(data[i]); // <<
}
source.push_back(0x80);
for(int i=0; i<K; i++)
source.push_back(0x00);
SIZE64 x = L*8; // <<
for(int i=sizeof(SIZE64)-1; i>=0; i--) { // big-endian
source.push_back(x >> i*8);
}
}
EDIT4: variable size in for loop
As "chux - Reinstate Monica" pointed out, it may be a problem if the size of the data is bigger than INT_MAX. All for-loop using a size as the upper limit should use a size_t type counter(instead of int) to prevent this problem.
// in BlockHeader::bytes()
for (size_t i=0; i<hashPrevBlock.size(); i+=2)
// in Sha256::hash()
for (size_t chunk=0; chunk<source.size()/64; chunk++)
// in main()
for (size_t i=0; i<h1.size(); i++)
for (size_t i=0; i<h2.size(); i++)
Notice that size_t is unsigned. The reverse version won't work because i is never less than 0.
for (size_t i=data.size()-1; i>=0; i--) // infinite loop
I have this piece of code in cpp on Visual Studio
((handrule1 - maskRule1[0]) & test)
All of the variables are unsigned int.
Their values are respectively
66848250
50138096
0x80808080.
I keep getting value zero as the outcome for this line, which should not be possible.
How does this come?
I already tried working with long unsigned variables instead.
I am guessing that maybe I am doing something else wrong when choosing the data types.
Underneath you can find my full code.
Some of the variables are not defined but that's because they are already defined in another cpp-file we are not supposed to use.
void init(void) {
int aa, ab, l, x = 0;
for (int i = 4; i <= 13; i++) {
aa = 13 - i;
for (int j = (aa + 2) / 3; j <= i && j <= aa; j++) {
ab = aa - j;
for (int k = (ab + 1) / 2; k <= j && k <= ab; k++) {
adj[x] = i + j - 8;
l = ab - k; code[x++] = (((i - 4) * 7) + j) * 5 + k;
// printf("%d %d %d %d: %d\n", i, j, k, l, (((i-4)*7)+j)*5+k);
}
}
}
return;
}
char countSetBits(long long unsigned n)
{
if (n == 0)
return 0;
else
return 1 + countSetBits(n & (n - 1));
}
void init_set(void) {
long long unsigned hand = 0;
char honorPoints = 0;
char nrOfSpades = 0;
char nrOfHearts = 0;
char nrOfDiamonds = 0;
char nrOfClubs = 0;
long long unsigned maskAces = 0x8004002001;
long long unsigned maskKings = 0x10008004002;
long long unsigned maskQueens = 0x20010008004;
long long unsigned maskJacks = 0x40020010008;
long long unsigned maskSpades = 0x1FFF;
long long unsigned maskHearts = 0x3FFE000;
long long unsigned maskDiamonds = 0x7FFC000000;
long long unsigned maskClubs = 0xFFF8000000000;
char upperbound[RU][4];
char lowerbound[RU][4];
unsigned int handrule1 = 0;
unsigned int handrule2 = 0;
unsigned int handrule3 = 0;
unsigned int maskRule1[RU];
unsigned int maskRule2[RU];
unsigned int maskRule3[RU];
unsigned int maskInverse = 0x00FF00FF;
unsigned int test = 0x80808080;
unsigned int result1 = 0;
bool applicableRule = false;
unsigned int fuck = 0xFF936636;
result1 = fuck & test;
for (int r = 0; r < nrr; r++)
{
for (int i = 0; i < 4; i++)
{
upperbound[r][i] = 13;
lowerbound[r][i] = 0;
}
}
for (int r = 0; r < nrr; r++)
{
if (res[r] != 0)
{
for (int i = 0; i < res[r]; i++)
{
upperbound[r][color[r][i]] = (char) nru[r][i];
lowerbound[r][color[r][i]] = (char) nrl[r][i];
}
}
maskRule1[r] = (((char) distl[r] << 24) | ((char) distu[r] << 16) | ((char) ahpl[r] << 8) | (char) ahpu[r]) ^ maskInverse;
maskRule2[r] = ((lowerbound[r][0] << 24) | (upperbound[r][0] << 16) | (lowerbound[r][1] << 8) | upperbound[r][1]) ^ maskInverse;
maskRule3[r] = ((lowerbound[r][2] << 24) | (upperbound[r][2] << 16) | (lowerbound[r][3] << 8) | upperbound[r][3]) ^ maskInverse;
}
int x[52], y, a;
for (int i = 0; i < 52; i++) x[i] = i;
srand(1);
for (int i = 0; i < CRD; i++) {
for (int j = 52; --j > 1;) {
y = rand() % j;
a = x[y]; x[y] = x[j]; x[j] = a;
}
for (int j = 0; j < 4; j++)
{
for (int k = 13 * j; k < 13 * (j + 1); k++)
{
hand |= 1LLU << x[k];
}
//Counting honorpoints
honorPoints = (countSetBits(hand & maskAces) * 4) + (countSetBits(hand & maskKings) * 3) + (countSetBits(hand & maskQueens) * 2) + (countSetBits(hand & maskJacks) * 1);
hp[i][j] = (char) honorPoints;
honorPoints = 0;
//Counting distributions
nrOfSpades = countSetBits(hand & maskSpades);
nrOfHearts = countSetBits(hand & maskHearts);
nrOfDiamonds = countSetBits(hand & maskDiamonds);
nrOfClubs = countSetBits(hand & maskClubs);
std::array<char, 4> arrayTest = { nrOfSpades, nrOfHearts, nrOfDiamonds, nrOfClubs };
std::sort(arrayTest.begin(), arrayTest.end());
char p = arrayTest[3];
char o = arrayTest[2];
char m = arrayTest[1];
int test = (((p - 4) * 7) + o) * 5 + m;
for (int x = 0; x < 39; x++)
{
if (code[x] == test)
{
dis[i][j] = (char) x;
}
}
//Counting opening bids
ahp[i][j] = hp[i][j] + adj[dis[i][j]];
if (ahp[i][j] < 0) ahp[i][j] = 0;
handrule1 = ((dis[i][j] << 24) | (dis[i][j] << 16) | (ahp[i][j] << 8) | ahp[i][j]) ^ maskInverse;
handrule2 = ((nrOfSpades << 24) | (nrOfSpades << 16) | (nrOfHearts << 8) | nrOfHearts) ^ maskInverse;
handrule3 = ((nrOfDiamonds << 24) | (nrOfDiamonds << 16) | (nrOfClubs << 8) | nrOfClubs) ^ maskInverse;
printf("%u \n", handrule1);
printf("%u \n", maskRule1[0]);
for (int r = 0; r < nrr; r++)
{
if ((((handrule1 - maskRule1[r]) & test) == 0) && (((handrule2 - maskRule2[r]) & test) == 0) && (((handrule3 - maskRule3[r]) & test) == 0))
{
cnt[bid[r]][j]++;
applicableRule = true;
break;
}
}
if (applicableRule == false)
{
cnt[0][j]++;
}
applicableRule = false;
handrule1 = 0;
handrule2 = 0;
handrule3 = 0;
nrOfSpades = 0;
nrOfHearts = 0;
nrOfDiamonds = 0;
nrOfClubs = 0;
hand = 0;
}
}
return;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
This program is built to run 10000 generations of 200 robots, allowing evolution to shape the digits in the robot's "DNA". The problem I'm having is that, even though there is nothing but numbers going into the 'robotGenes' array, the resulting DNA that prints is a random collection of letters, numbers and symbols. I have absolutly no idea why. I have tried switching up where I declare and assign my variables, unfortunatly its all been in vane. Plz halp.
P.s. I'm posting the entire program code here, as I am unsure what is causing the problem, though I am positive that I am simply being daft. Any help is greatly appreciated.
#include <iostream>
#include <string>
#include <stdlib.h>
#include <cmath>
using namespace std;
int randBattery = 0,
randRobot = 0,
randDirect = 0,
board[144] = { },
testDirect = 0,
randTurn = 0,
randTurnDirect = 0,
genAdd = 0,
masterFit = 0,
abc = 0;
double fitness[10000] = { },
winners[5] = { };
std::string startCond;
unsigned char robotGenes[200][12] = { },
test[12] = { };
class Display {
public:
int results() {
cout << "\n\n\n-Evolution Winning Avg. Fitness Ratings-\n\n";
cout << "1. " << winners[1];
cout << "\n DNA: ";
for (int G = 1; G <= 12; G++)
{
cout << robotGenes[1][G];
}
cout << "\n\n2. " << winners[2];
cout << "\n DNA: ";
for (int G = 1; G <= 12; G++)
{
cout << robotGenes[41][G];
}
cout << "\n\n3. " << winners[3];
cout << "\n DNA: ";
for (int G = 1; G <= 12; G++)
{
cout << robotGenes[81][G];
}
cout << "\n\n4. " << winners[4];
cout << "\n DNA: ";
for (int G = 1; G <= 12; G++)
{
cout << robotGenes[121][G];
}
cout << "\n\n5. " << winners[5];
cout << "\n DNA: ";
for (int G = 1; G <= 12; G++)
{
cout << robotGenes[161][G];
}
return 0;
};
};
class RobotSex {
public:
int bang() {
int newGen, newGen2, B;
newGen = 101;
newGen2 = 102;
B = 2;
for (int C = 1; C <= 100; C += 2)
{
robotGenes[newGen][6] = robotGenes[C][6];
robotGenes[newGen][7] = robotGenes[C][7];
robotGenes[newGen][8] = robotGenes[C][8];
robotGenes[newGen][9] = robotGenes[C][9];
robotGenes[newGen][10] = robotGenes[B][10];
robotGenes[newGen][11] = robotGenes[B][11];
robotGenes[newGen2][6] = robotGenes[B][6];
robotGenes[newGen2][7] = robotGenes[B][7];
robotGenes[newGen2][8] = robotGenes[B][8];
robotGenes[newGen2][9] = robotGenes[B][9];
robotGenes[newGen2][10] = robotGenes[C][10];
robotGenes[newGen2][11] = robotGenes[C][11];
newGen += 2;
newGen2 += 2;
B += 2;
}
};
};
class Genocide {
public:
int ethnicCleansing() {
for (int x = 101; x <= 200; x++)
{
for (int y = 6; y <= 12; y++)
{
robotGenes[x][y] = 0;
}
}
};
};
class Sorting {
public:
int sortPower() {
for (int P = 0; P <= 200; P++)
{
for (int x = 1; x <= 200; x++)
{
int y;
y = x + 1;
if (robotGenes[x][12] < robotGenes[y][12])
for (int Q = 1; Q <= 12; Q++)
swap (robotGenes[x][Q], robotGenes[y][Q]);
}
}
};
int addGenFit() {
for (int o = 1; o <= 200; o++)
{
genAdd += robotGenes[o][12];
}
fitness[masterFit] = genAdd / 200;
::masterFit += 1;
};
int sortGenFit() {
for (int P = 0; P <= 10000; P++)
{
for (int x = 1; x <= 9999; x++)
{
int y;
y = x + 1;
if (fitness[x] < fitness[y])
swap (fitness[x], fitness[y]);
}
}
for (int o = 1; o <= 2000; o++)
{
genAdd += fitness[o];
}
winners[1] = genAdd / 2000;
for (int o = 2001; o <= 4000; o++)
{
genAdd += fitness[o];
}
winners[2] = genAdd / 2000;
for (int o = 4001; o <= 6000; o++)
{
genAdd += fitness[o];
}
winners[3] = genAdd / 2000;
for (int o = 6001; o <= 8000; o++)
{
genAdd += fitness[o];
}
winners[4] = genAdd / 2000;
for (int o = 8001; o <= 10000; o++)
{
genAdd += fitness[o];
}
winners[5] = genAdd / 2000;
};
};
class Establishing {
public:
int clearBoard() {
for (int c = 0; c <= 144; c++) //Clearing board
{
board[c] = 0;
}
for (int x = 0; x <= 12; x++) //Establishing walls
{
board[x] = 9;
}
for (int x = 132; x <= 144; x++)
{
board[x] = 9;
}
for (int x = 13; x <= 121; x += 12)
{
board[x] = 9;
}
for (int x = 24; x <= 132; x += 12)
{
board[x] = 9;
}
};
};
class Randomizer {
public:
int randBattery() {
for (int t = 1; t <= 4; t++)
{
srand(time(NULL)); //Random battery placement R1
::randBattery = (rand() % 14+23);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL)); //Random battery placement R2
::randBattery = (rand() % 26+35);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL)); //Random battery placement R3
::randBattery = (rand() % 38+47);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL)); //Random battery placement R4
::randBattery = (rand() % 50+59);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL)); //Random battery placement R5
::randBattery = (rand() % 62+71);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL)); //Random battery placement R6
::randBattery = (rand() % 74+82);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL)); //Random battery placement R7
::randBattery = (rand() % 85+95);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL)); //Random battery placement R8
::randBattery = (rand() % 98+107);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL)); //Random battery placement R9
::randBattery = (rand() % 110+119);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL)); //Random battery placement R10
::randBattery = (rand() % 122+131);
board[::randBattery] = 1;
}
};
int randPlacement() {
for (int t = 1; t <= 200; t++)
{
srand(time(NULL)); //Random robot placement & resets power level
randRobot = (rand() % 62+71);
robotGenes[t][1] = randRobot;
robotGenes[t][12] = 5;
}
};
char randDirect() {
for (int d = 1; d <= 200; d++)
{
srand(time(NULL)); //Random robot direction
::randDirect = (rand() % 62+71);
robotGenes[d][5] = ::randDirect;
}
};
};
class Reader {
public:
int readDNA() {
do {
if (board[test[1]] == 1) //Pickup battery
test[12] += 5;
if (test[9] == 1) //Check for wall
{
if (board[test[2]] == 9)
{
if (test[5] == 1)
test[5] = 4;
if (test[5] == 2)
test[5] = 1;
if (test[5] == 3)
test[5] = 2;
if (test[5] == 4)
test[5] = 3;
}
if (board[test[2]] == 9 && board[test[3]] == 9)
{
if (test[5] == 1)
test[5] = 2;
if (test[5] == 2)
test[5] = 3;
if (test[5] == 3)
test[5] = 4;
if (test[5] == 4)
test[5] = 1;
}
}
if (test[7] == test[6]) //Changing direction after # of moves
if (test[6] % 2 == 0) //Turning left
{
if (test[5] == 1)
test[5] = 4;
if (test[5] == 2)
test[5] = 1;
if (test[5] == 3)
test[5] = 2;
if (test[5] == 4)
test[5] = 3;
}
else //Turning right
{
if (test[5] == 1)
test[5] = 2;
if (test[5] == 2)
test[5] = 3;
if (test[5] == 3)
test[5] = 4;
if (test[5] == 4)
test[5] = 1;
}
if (test[10] == 1) //Left sensor checking for battery, TURN LEFT
if (test[5] == 1)
test[5] = 4;
if (test[5] == 2)
test[5] = 1;
if (test[5] == 3)
test[5] = 2;
if (test[5] == 4)
test[5] = 3;
if (test[11] == 1) //Right sensor checking for battery, TURN RIGHT
if (test[5] == 1)
test[5] = 2;
if (test[5] == 2)
test[5] = 3;
if (test[5] == 3)
test[5] = 4;
if (test[5] == 4)
test[5] = 1;
if (test[5] == 1) //Face north
{
test[2] = test[1] + 12;
::test[3] = test[1] - 1;
test[4] = test[1] + 1;
test[1] += 12; //Move north
test[2] += 12;
::test[3] += 12;
test[4] += 12;
}
if (test[5] == 2) //Face east
{
test[2] = test[1] + 1;
::test[3] = test[1] + 12;
test[4] = test[1] - 12;
test[1] += 1; //Move east
test[2] += 1;
::test[3] += 1;
test[4] += 1;
}
if (test[5] == 3) //Face south
{
test[2] = test[1] - 12;
::test[3] = test[1] + 1;
test[4] = test[1] - 1;
test[1] -= 12; //Move south
test[2] -= 12;
::test[3] -= 12;
test[4] -= 12;
}
if (test[5] == 4) //Face west
{
test[2] = test[1] - 1;
::test[3] = test[1] - 12;
test[4] = test[1] + 12;
test[1] -= 1; //Move west
test[2] -= 1;
::test[3] -= 1;
test[4] -= 1;
}
test[7] += 1;
test[12] -= 1;
} while (test[12] > 1 && test[7] < 24);
};
};
class Running {
public:
void runRobot() {
for (int q = 1; q <= 200; q++)
{
for (int z = 1; z <= 12; z++)
{
::test[z] = robotGenes[q][z];
}
Reader objectDNA;
objectDNA.readDNA();
for (int z = 1; z <= 12; z++)
{
::robotGenes[q][z] = test[z];
}
}
};
};
int main()
{
//System Greeting
cout << "Enter anything to start simulation.\n\n";
cin >> startCond;
masterFit = 1;
//Setting starting genes
for (int t = 1; t <= 200; t++)
{
srand(time(NULL));
randTurn = (rand() % 10+1);
robotGenes[t][6] = randTurn;
}
for (int o = 1; o <= 40; o++)
{
robotGenes[o][8] = 1;
robotGenes[o][9] = 0;
robotGenes[o][10] = 0;
robotGenes[o][11] = 0;
}
for (int o = 41; o <= 80; o++)
{
robotGenes[o][8] = 0;
robotGenes[o][9] = 1;
robotGenes[o][10] = 1;
robotGenes[o][11] = 1;
}
for (int o = 81; o <= 120; o++)
{
robotGenes[o][8] = 1;
robotGenes[o][9] = 1;
robotGenes[o][10] = 0;
robotGenes[o][11] = 0;
}
for (int o = 121; o <= 160; o++)
{
robotGenes[o][8] = 0;
robotGenes[o][9] = 0;
robotGenes[o][10] = 0;
robotGenes[o][11] = 0;
}
for (int o = 161; o <= 200; o++)
{
robotGenes[o][8] = 1;
robotGenes[o][9] = 0;
robotGenes[o][10] = 1;
robotGenes[o][11] = 1;
}
//Running sims (not the game)
Randomizer objectRaDirect;
objectRaDirect.randDirect();
Randomizer objectRaPlace;
objectRaPlace.randPlacement();
for (int sims = 1; sims <= 10000; sims++)
{
Establishing objectClear;
objectClear.clearBoard();
Randomizer objectRaBattery;
objectRaBattery.randBattery();
Running objectRun;
objectRun.runRobot();
abc += 1;
cout << "\n\nGeneration " << abc << " is complete.\n";
Sorting objectPower;
objectPower.sortPower();
Sorting objectGenFit;
objectGenFit.addGenFit();
Genocide objectHitler;
objectHitler.ethnicCleansing();
RobotSex objectSex;
objectSex.bang();
}
Sorting objectWin;
objectWin.sortGenFit();
for (int B = 1; B <= 5; B++)
{
winners[B] = abs (winners[B]);
}
Display objectEnd;
objectEnd.results();
};
You have two major issues with your code:
1) You have an out-of-bounds array access here:
unsigned char robotGenes[200][12] = { }, test[12] = { };
//...
for (int G = 1; G <= 12; G++)
{
cout << robotGenes[1][G];
}
On the last iteration, you are printing a garbage value. The program actually invokes undefined behavior, since robotGenes[1][G] is out-of-bounds when G is 12.
You are also making the same mistake in the ethnicCleansing function, but probably even worse since you are not just reading an invalid location, you are writing to it:
for (int y = 6; y <= 12; y++)
{
robotGenes[x][y] = 0;
}
When y is 12, you are writing to an invalid index.
Array indices start from 0 up to n-1, where n is the total number of entries in the array. Thus G ranges from 0 to 11, inclusive. Going to index 12 is an out-of-bounds access.
2) You are calling functions that are supposed to return a value, but fail to do so. For example,
int Genocide::ethnicCleansing
This function is supposed to return an int, but doesn't return anything. Thus your program invokes undefined behavior. Not returning a value from a function that is supposed to return a value is undefined behavior. Note that you have several other functions with the same issue.
Please see your full code here.
Fix the warnings, fix the out-of-bounds accesses first. I don't know if these will be the only problems, but they are the two that stick out like sore thumbs.
You are most likely printing the data as a char array instead of an unsigned char array. This causes ASCII characters represented by the numbers to be printed instead of the actual numbers.
I have such a code:
QVector<Point> legalMoves = field.getLegalMoves();
QVector<Cell> costs;
costs.reserve(legalMoves.size());
for (QVector<Point>::iterator i = legalMoves.begin(); i < legalMoves.end(); ++i)
costs.push_back(checkCost(field, *i, player, -100, 100));
Cell cost;
if (player) {
QVector<Point>::iterator m1 = legalMoves.begin();
QVector<Cell>::iterator m2 = costs.begin();
QVector<Cell>::iterator j = costs.begin() + 1;
for (QVector<Point>::iterator i = legalMoves.begin() + 1; i < legalMoves.end(); ++i, ++j)
if (j->status > m2->status) {
m1 = i;
m2 = j;
}
cost=*m2;
}
else {
QVector<Point>::iterator m1 = legalMoves.begin();
QVector<Cell>::iterator m2 = costs.begin();
QVector<Cell>::iterator j = costs.begin() + 1;
for (QVector<Point>::iterator i = legalMoves.begin() + 1; i < legalMoves.end(); ++i, ++j)
if (j->status < m2->status) {
m1 = i;
m2 = j;
}
cost=*m2;
}
QVector<Point> moves;
QVector<Cell>::iterator j = costs.begin();
for (QVector<Point>::iterator i = legalMoves.begin(); i < legalMoves.end(); ++i, ++j)
if (j->status == cost.status)
moves.push_back(*i);
short index = qrand()%moves.size();
return moves[index];
}
When i'm debugging it, compiler just skips this parts inside loops:
if (j->status < m2->status) {
m1 = i;
m2 = j;
}
which means the functions returns the very first Point(or any other Point with same Cell value instead of min/max). Why does that happen and how is it possible to fix it?