Reputation: 51
The following is one example of several that seemingly randomly the other night started resulting in weird ascii characters being display in console. For example the player.level displays a smiley face ascii character. Some displays simply several blank spaces, others display single weird ascii characters.
Image example:
The code worked fine and I was having some compiler issues that I fixed. Around the same time I changed a lot of "int" data types to uint8_t etc. Once I fixed the compiler issues I started seeing this new issue.
Language: C++(11) (CodeBlocks IDE)
//randstats.cpp
#include "encounter.h"
#include "player.h"
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <iostream>
#include "createchar.h"
#include "randstats.h"
boost::random::mt19937 gen;
player_vars randStats()
{
/*
Randomize new characters stats if the player chooses to do so rather than manually assign them.
Also going to use this to test against random encounters for balance purposes.
*/
player.str = 8;
player.dex = 8;
player.con = 8;
player.intel = 8;
player.wis = 8;
player.cha = 8;
uint8_t remaining_points = 25; // starting pts to hand out freely
uint8_t total_possible = player.str + player.dex + player.con + player.intel + player.wis + player.cha + remaining_points; // max points to assign
/*
Basically the whole purpose of this is to pick random numbers and spread them out among random stats.
The stats will not be higher than total_possible + remaining points (assigned above).
*/
while (remaining_points > 0)
{
boost::random::uniform_int_distribution<> dist13(1, 3);
uint8_t random_number = dist13(gen);
uint8_t x = 0;
// Get current or total points currently assigned
uint8_t totalpts = player.str + player.dex + player.con + player.intel + player.wis + player.cha;
//if we're in range and won't go over
if ((totalpts < total_possible) && ((random_number + totalpts) < total_possible))
{
x = random_number;
// remaining_points - x;
}
//if we're going to go over, only assign the number of points from random that will stop us at 73 points
else if ((random_number + totalpts) > total_possible)
{
// Since we're going over the max total points, how many do we assign to a stat?
uint8_t y = totalpts - total_possible;
x = abs(y);
remaining_points = 0; //force this because we exceeded
}
//random numbering choosing which stat the points go to
boost::random::uniform_int_distribution<> dist16(1, 6);
switch(dist16(gen))
{
case 1 :
player.str += x;
break;
case 2 :
player.dex += x;
break;
case 3 :
player.con += x;
break;
case 4 :
player.intel += x;
break;
case 5 :
player.wis += x;
break;
case 6 :
player.cha += x;
break;
default :
break;
}
}
//print the new results
std::cout << "\nNew Character Stats: \n";
std::cout << "Strength: [" << player.str << "]" << std::endl;
std::cout << "Dexterity: [" << player.dex << "]" << std::endl;
std::cout << "Constitution: [" << player.con << "]" << std::endl;
std::cout << "Intelligence: [" << player.intel << "]" << std::endl;
std::cout << "Wisdom: [" << player.wis << "]" << std::endl;
std::cout << "Charisma: [" << player.cha << "]" << std::endl;
std::cout << "Total Points Assigned: " << player.str + player.dex + player.con + player.intel + player.wis + player.cha << std::endl;
std::cout << "Accept these results? [y/n]: ";
char selection;
std::cin >> selection;
switch(selection)
{
case 'Y' :
case 'y' :
createPlayer();
break;
case 'N' :
case 'n' :
randStats();
break;
default:
std::cout << "\nInvalid response. Keeping results.\n";
createPlayer();
}
return player;
}//close function
//player.h
#ifndef PLAYER_H_INCLUDED
#define PLAYER_H_INCLUDED
#include <string>
#include <cstdint>
struct player_vars {
std::string alias;
uint8_t current_level;
bool is_alive; // alive or dead
uint8_t str;
uint8_t dex;
uint8_t con;
uint8_t intel;
uint8_t wis;
uint8_t cha;
uint32_t gold;
std::string profileName; // may use
int16_t hitpoints; // current HP dependent on class, level, feats, con, etc.
uint8_t size_id; // character size
uint8_t class_id; // check comments
uint8_t base_attack_bonus; // dependent on player's class
uint8_t weapon_id; // check comments
uint8_t getHitPoints();
}; extern player_vars player;
Upvotes: 1
Views: 2191
Reputation: 137537
uint8_t
is usually typedef
'd to unsigned char
. This works great in C.
C++'s stream operators are seeing your unsigned char
values and trying to print them as characters, instead of converting the integer to a string. So what you're seeing is whatever the particular terminal/console decides to display for that character code.
Save yourself the trouble, and just stick with int
. We're only talking 4 bytes instead of 1. And not having to worry about the awfully tiny limit of 255.
If you really want to store your data as uint_8
, you'll want to cast to int
before streaming it to cout
:
std::cout << "Strength: [" << (int)player.str << "]" << std::endl;
Upvotes: 2