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.
Related
I'm trying to export application data as xls chart.
I'm doing it using SimpleXlsxWriter.
But I have some problems with this lib.
Here's what I got using this lib
#include <Xlsx/Workbook.h>
int main()
{
using namespace SimpleXlsx;
CWorkbook book;
CWorksheet &data = book.AddSheet("Data");
std::vector<CellDataDbl> header = { 1, 3, 5, 6, 8 };
std::vector<CellDataDbl> data1 = { 2, 6, 4, 8, 5 };
std::vector<CellDataDbl> data2 = { 5, 3, 5, 2, 4 };
data.AddRow(header);
data.AddRow(data1);
data.AddRow(data2);
CChartsheet &chart = book.AddChart("Chart", CHART_BAR);
chart.SetBarDirection(CChartsheet::BAR_DIR_VERTICAL);
chart.SetBarGrouping(CChartsheet::BAR_GROUP_STACKED);
chart.SetTableDataState(CChartsheet::TBL_DATA);
chart.SetLegendPos(CChartsheet::EPosition::POS_TOP);
CChartsheet::Series ser1;
ser1.valAxisFrom = CellCoord(1, 0);
ser1.valAxisTo = CellCoord(1, data1.size() - 1);
ser1.valSheet = &data;
ser1.title = "Ser1";
CChartsheet::Series ser2;
ser2.valAxisFrom = CellCoord(2, 0);
ser2.valAxisTo = CellCoord(2, data2.size() - 1);
ser2.valSheet = &data;
ser2.title = "Ser2";
chart.AddSeries(ser1);
chart.AddSeries(ser2);
book.Save("test.xls");
}
I didn't find the ways how to show y-axes, show horizontal lines, set x-axes values, insert the chart into the data sheet, etc.
Here's what do I want to get as a result
What a library can help me or how can I get a required result? Maybe SimpleXlsxWriter can do that?
You can get what you want from the SimpleXlsxWriter, just with a few modifications of your code. Briefly:
save with SimpleXlsxWriter's format .xlsx not .xls
Add a category axis to one of your series and set it to first data row
use BAR_GROUP_PERCENT_STACKED since you want the y axis to be on % scale
You can control the order you add the series the the chart, to get the order you want in the bottom table
Consider this code, suggested modifications are indicated in comments:
int main()
{
using namespace SimpleXlsx;
CWorkbook book;
CWorksheet &data = book.AddSheet("Data");
std::vector<CellDataDbl> header = { 1, 3, 5, 6, 8 };
std::vector<CellDataDbl> data1 = { 2, 6, 4, 8, 5 };
std::vector<CellDataDbl> data2 = { 5, 3, 5, 2, 4 };
data.AddRow(header);
data.AddRow(data1);
data.AddRow(data2);
CChartsheet &chart = book.AddChart("Chart", CHART_BAR);
chart.SetBarDirection(CChartsheet::BAR_DIR_VERTICAL);
chart.SetBarGrouping(CChartsheet::BAR_GROUP_PERCENT_STACKED); // <-- seems you want this format?
chart.SetTableDataState(CChartsheet::TBL_DATA);
chart.SetLegendPos(CChartsheet::EPosition::POS_TOP);
chart.SetYAxisGrid(CChartsheet::EGridLines::GRID_MAJOR); // <-- to draw the horizontal lines
CChartsheet::Series ser1;
ser1.valSheet = &data;
ser1.valAxisFrom = CellCoord(1, 0);
ser1.valAxisTo = CellCoord(1, data1.size() - 1);
ser1.title = "Ser1";
// Now add a category axis from your the first row of the data sheet
ser1.catAxisFrom = CellCoord(0, 0);
ser1.catAxisTo = CellCoord(0, data1.size() - 1);
ser1.catSheet = &data;
CChartsheet::Series ser2;
ser2.valSheet = &data;
ser2.valAxisFrom = CellCoord(2, 0);
ser2.valAxisTo = CellCoord(2, data2.size() - 1);
ser2.title = "Ser2";
// insert the series in the order you want from the bottom up in the chart's table
chart.AddSeries(ser2);
chart.AddSeries(ser1);
book.Save("c:\\so\\test.xlsx"); // <-- Save as xlsx, not xls
}
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.
SOLVED! (See Edit)
I am trying to initialize an couple of arrays that are private members of a class. I am trying to use a public function to initialize these private arrays. My code looks like this:
void AP_PitchController::initGains(void){
_fvelArray[] = {20, 25, 30, 60, 90, 130, 160, 190, 220, 250, 280};
_kpgArray[] = {6.0, 6.0, 8.0, 4.0, 3.0, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5};
_kdgArray[] = {2000, 2000, 1900, 300, 300, 200, 200, 200, 200, 200, 200};
_kigArray[] = {0.1, 0.1, 0.2, 0.25, 0.3, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5};
}
These arrays are found in the header file AP_PitchController where they are declared private. When I try to compile the code, I get one of these messages for each initialization:
/../AP_PitchController.cpp:106: error: expected primary-expression before ']' token
/../AP_PitchController.cpp:106: error: expected primary-expression before '{' token
/../AP_PitchController.cpp:106: error: expected `;' before '{' token
And here are my private declarations:
Private:
uint8_t _fvelArray[];
float _kpgArray[];
float _kdgArray[];
float _kigArray[];
Does anyone know what I am doing wrong to initialize these arrays upon the call of initGains()?
EDIT:
I found the answer in one of the related questions.
All i need to do is provide an array size for the initialization:
static float _kpgArray[11];
And then initialize it outside of a function in the .cpp file:
uint8_t AP_PitchController::_fvelArray[11] = {20, 25, 30, 60, 90, 130, 160, 190, 220, 250, 280};
Thank you for your input!
You can only use initialization syntax at declaration:
float _array[2] = {0.1f, 0.2f};
After it is declared you will have to initialize the members individually:
_array[0] = 0.1f;
_array[1] = 0.2f;
Or you could do it in a loop:
float temp[2] = {0.1f, 0.2f};
for( int i = 0; i < 2; ++i )
_array[i] = temp[i];
First, you cannot use the the initialization-list syntax that you're using since you've already declared your arrays (e.g. uint8_t _fvelArray = { ... }; would be valid when you first declare it under private: but _fvelArray = { ... }; is not valid in your initGains method). You must also declare the size of each array in your private declarations:
private:
uint8_t _fvelArray[10]; // or whatever size you want
Once you've taken those steps, you can populate the arrays:
_fvelArray[0] = 20;
_fvelArray[1] = 25;
// ...
Is there a reason you don't initialize your arrays right away? Will the gain values change? Your method is called initGains after all. If not, use the initializer-list syntax at the point of declaration:
private:
uint8_t _fvelArray[] = {20, 25, 30, 60, 90, 130, 160, 190, 220, 250, 280};
You have several issues here:
uint8_t _fvelArray[]; does not declare an array, but a pointer, the same as uint8_t *_fvelArray;. If you want to declare fixed-size array, you need to write uint8_t _fvelArray[11]; or in c++11 std::array<uint8_t, 11> _fvelArray;. For variable-length array you should use std::vector<uint8_t> _fvelArray;.
{20, ...} expression is an initializer-list an cannot be used for array initialization outside of its definition. That means that you can write uint8_t _fvelArray_tmp[] = {20, ...}; and then copy it to your variable : memcpy (_fvelArray, _fvelArray_tmp, sizeof (_fvelArray_tmp)); but not to initialize some already existing variable. But if you use std::array or std::vector for _fvelArray type, you could simply write _fvelArray = {20, ...}; (but it only works for c++11).
In an effort to reduce multiple functions (that were nearly identical) in my code, I decided to consolidate them all into one function which takes an additional parameter (a class with multiple parameters, actually), and then uses those values to imitate what the multiple functions would have done. Then, long story short, I put each of those class declarations into a vector, and now my program seems dysfunctional.
My multiple instances of a class:
FragmentCostParameters commonFCP = FragmentCostParameters(.05, 0);
FragmentCostParameters rareFCP = FragmentCostParameters(.05, 50);
FragmentCostParameters uniqueFCP = FragmentCostParameters(.05, 125);
FragmentCostParameters legendaryFCP = FragmentCostParameters(.02, 175);
FragmentCostParameters crystallineFCP = FragmentCostParameters(.02, 250);
FragmentCostParameters superEliteFCP = FragmentCostParameters(.02, 300);
Which get placed into a vector by:
vector<FragmentCostParameters> FCPs(6);
FCPs.push_back(FragmentCostParameters(.05, 0));
FCPs.push_back(FragmentCostParameters(.05, 50));
FCPs.push_back(FragmentCostParameters(.05, 125));
FCPs.push_back(FragmentCostParameters(.02, 175));
FCPs.push_back(FragmentCostParameters(.02, 250));
FCPs.push_back(FragmentCostParameters(.02, 300));
Additionally, that class is defined below:
class FragmentCostParameters {
public:
double multFactor;
double subtractFactor;
FragmentCostParameters(double _multFactor, double _subtractFactor){
multFactor = _multFactor;
subtractFactor = _subtractFactor;
}
FragmentCostParameters(){
multFactor = .05;
subtractFactor = 0;
}
};
Now, you'll notice that the default constructor for the FragmentCostParameters involves setting multFactor = .05 and subtractFactor = 0. However, it seems that no matter what I push back, each of the values in my vector become mutated into those values. At least, that's what VS 2011 tells me the values are equal to when I'm looking at them in a local scope in the following function (which is the only place they're used).
int FragmentCost(double skillLevel, int duration, FragmentCostParameters FCP){
return max((int)(ceil(FCP.multFactor*(skillLevel-FCP.subtractFactor))*ceil(duration/30.0)) , 0);
}
And the only place that FragmentCost is called is from this function below, which is supposed to pass different values .. but somewhere in the process, when I look at locals in FragmentCost, they're always the default values in the constructor for the class.
//given a skill level + duration, will return an array with the fragment usage
int* regularTotalFragCost(int skillLevel, int duration){
int fragments[7] = {0,0,0,0,0,0,0};
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[0]);
fragments[1]+= FragmentCost(skillLevel,duration, FCPs[0]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[1]);
fragments[2]+= FragmentCost(skillLevel,duration, FCPs[1]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[2]);
fragments[3]+= FragmentCost(skillLevel,duration, FCPs[2]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[3]);
fragments[4]+= FragmentCost(skillLevel,duration, FCPs[3]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[4]);
fragments[5]+= FragmentCost(skillLevel,duration, FCPs[4]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[5]);
fragments[6]+= FragmentCost(skillLevel,duration, FCPs[5]);
return fragments;
}
For some reason I feel that I'm making a really stupid mistake somewhere, but for the life of me I can't seem to figure it out. I would appreciate any help and/or advice anyone could offer.
EDIT: Here's what the values for fragments[] in regularTotalFragCost are supposed to be if everything is working correctly, using a couple test values (skillLevel = 250 and duration = 30)
FCPs[0] : Fragments: 13, 13, 0, 0, 0, 0, 0,
FCPs[1] : Fragments: 17, 15, 2, 0, 0, 0, 0,
FCPs[2] : Fragments: 20, 14, 5, 1, 0, 0, 0,
FCPs[3] : Fragments: 29, 14, 9, 5, 1, 0, 0,
FCPs[4] : Fragments: 32, 13, 10, 7, 2, 0, 0,
FCPs[5] : Fragments: 32, 13, 10, 7, 2, 0, 0,
And here is what they are as of right now:
FCPs[0] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[1] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[2] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[3] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[4] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[5] : Fragments: 78, 13, 13, 13, 13, 13, 13,
vector<FragmentCostParameters> FCPs(6);
creates a vector of 6 default-constructed values, numbered 0-5.
FCPs.push_back(FragmentCostParameters(.05, 0));
adds value at index 6
int fragments[7] is a local variable on the stack. Once that function returns, that memory is no longer valid. You are returning a pointer to that local variable and any access to that memory is undefined behavior.
Instead, return an std::array:
std::array<int, 7> fragments = {}; // value initialize
return fragments;
Hint: How big is your vector after you push_back your FCPs?
I'm currently working on a project in which I load a huge number of data points on a graph (something like 50,000, so I can zoom in as much as I want).
I wanted to test how the commands worked, so I thought I'd try out the code with 10 pieces of data, but unfortunately my curve refuses to show up on my graph.
QwtPlot *leftGraph;
leftGraph = new QwtPlot;
leftGraph->setCanvasBackground(Qt::white);
leftGraph->setMaximumHeight(200);
leftGraph->setAxisScale(0, 0.0, 20.0, 2.0);
leftGraph->setAxisScale(2, 0.0, 20.0, 2.0);
and
QwtPlotCurve *curve = new QwtPlotCurve();
curve->setStyle(QwtPlotCurve::Lines);
curve->setCurveAttribute(QwtPlotCurve::Fitted, true);
const double x[] = {0, 1, 2, 4, 5, 8, 10, 13, 14, 19};
const double y[] = {17, 16.5, 8, 3, 5, 7.5, 9, 10, 12, 14};
curve->setSamples(x, y, 10);
curve->attach(leftGraph);
Any ideas? Many thanks.
Try calling leftGraph->replot() to make the curve appear.