Algorithm for 3D dice generation - c

I am making a simple test application in C that is supposed to generate three dimensional dice. I am going to use OpenGL to do the actual drawing, but I cannot figure out how to actually generate the vertices. Of course, the whole point of this test was to see if my algorithm worked, but I found a major logic error that I cannot fix. Can somebody please point me to an article, website, or something that explains the concept? If not, although I would prefer to do the actual implementation myself, the C code is acceptable.
Basically, this is what I did before I forgot what I was doing for the algorithm:
void calculateVertices(int sides) {
BOOL isDone = FALSE;
int vectorsPerSide = 3;
VDVector3f *vertices = malloc((sizeof(VDVector3f) * (sides + 1)));
VDVector3f *normals = malloc((sizeof(VDVector3f) * (sides + 1)));
while (!isDone) {
// Start by positioning the first vertex.
vertices[0] = VDVector3fMake(0.0, 0.0, 1.0);
for (int index = 1; index <= sides; index ++) {
}
// Not a match, increase the number of vectors
vectorsPerSide ++;
}
}
Basically, it loops until a match is found. This sounds inefficient to me, but I had no other idea as to how to do this. The first vertex will actually be removed from the array at the end; I was going to use it to create the first side, which would have been used to properly position the others.
My main goal here is to be able to pass number (like 30) to it, and have it set the vertices automatically. I will not have protections against making one sided and two sided dice, because I have something special in mind. I will have those vertices entered elsewhere.
Thanks in advance for the help!
By the way, I have an algorithm that can normalize the completed vertex array. You don't have to bother helping with that.

I don't think this is possible to generalize this. How, for example would you make a fair 5 or 9 sided die? I don't think I have ever seen such a thing. A quick search on wikipedia suggests platonic solids may be what you are after. http://en.wikipedia.org/wiki/Platonic_solid

Related

Theory of arrays in Z3: (1) model is difficult to understand, (2) do not know how to implement functions and (3) difference with sequences

Following to the question published in How expressive can we be with arrays in Z3(Py)? An example, I expressed the following formula in Z3Py:
Exists i::Integer s.t. (0<=i<|arr|) & (avg(arr)+t<arr[i])
This means: whether there is a position i::0<i<|arr| in the array whose value a[i] is greater than the average of the array avg(arr) plus a given threshold t.
The solution in Z3Py:
t = Int('t')
avg_arr = Int('avg_arr')
len_arr = Int('len_arr')
arr = Array('arr', IntSort(), IntSort())
phi_1 = And(0 <= i, i< len_arr)
phi_2 = (t+avg_arr<arr[i])
phi = Exists(i, And(phi_1, phi_2))
s = Solver()
s.add(phi)
print(s.check())
print(s.model())
Note that, (1) the formula is satisfiable and (2) each time I execute it, I get a different model. For instance, I just got: [avg_a = 0, t = 7718, len_arr = 1, arr = K(Int, 7719)].
I have three questions now:
What does arr = K(Int, 7719)] mean? Does this mean the array contains one Int element with value 7719? In that case, what does the K mean?
Of course, this implementation is wrong in the sense that the average and length values are independent from the array itself. How can I implement simple avg and len functions?
Where is the i index in the model given by the solver?
Also, in which sense would this implementation be different using sequences instead of arrays?
(1) arr = K(Int, 7719) means that it's a constant array. That is, at every location it has the value 7719. Note that this is truly "at every location," i.e., at every integer value. There's no "size" of the array in SMTLib parlance. For that, use sequences.
(2) Indeed, your average/length etc are not related at all to the array. There are ways of modeling this using quantifiers, but I'd recommend staying away from that. They are brittle, hard to code and maintain, and furthermore any interesting theorem you want to prove will get an unknown as answer.
(3) The i you declared and the i you used as the existential is completely independent of each other. (Latter is just a trick so z3 can recognize it as a value.) But I guess you removed that now.
The proper way to model such problems is using sequences. (Although, you shouldn't expect much proof performance there either.) Start here: https://microsoft.github.io/z3guide/docs/theories/Sequences/ and see how much you can push it through. Functions like avg will need a recursive definition most likely, for that you can use RecAddDefinition, for an example see: https://stackoverflow.com/a/68457868/936310
Stack-overflow works the best when you try to code these yourself and ask very specific questions about how to proceed, as opposed to overarching questions. (But you already knew that!) Best of luck..

How would Transposition Tables work with Hypermax?

I was wondering if someone out there could help me understand how Transposition Tables could be incorporated into the Hypermax algorithm. Any examples, pseudo-code, tips, or implementation references would be much appreciated!
A little background:
Hypermax is a recursive game tree search algorithm used for n-player
games, typically for 3+ players. It's an extension of minimax and
alpha beta pruning.
Generally at each node in the game tree the
current player (chooser) will look at all of the moves it can make
and choose the one that maximizes it's own utility. Different than
minimax / negamax.
I understand how transposition tables work, but I
don't know how the values stored in them would be used to initiate
cutoffs when a transposition table entry is found. A transposition
flag is required in minimax with transposition & alpha-beta pruning.
I can't seem to wrap my head around how that would be incorporated
here.
Hypermax Algorithm without Transposition Tables in Javascript:
/**
* #param {*} state A game state object.
* #param {number[]} alphaVector The alpha vector.
* #returns {number[]} An array of utility values for each player.
*/
function hypermax(state, alphaVector) {
// If terminal return the utilities for all of the players
if (state.isTerminal()) {
return state.calculateUtilities();
}
// Play out each move
var moves = state.getLegalMoves();
var bestUtilityVector = null;
for (var i = 0; i < moves.length; ++i) {
var move = moves[i];
state.doMove(move); // move to child state - updates game board and advances player 1
var utilityVector = hypermax(state, alphaVector.slice(0)); // copy the alpha values down
state.undoMove(move); // return to this state - remove board updates and rollsback player 1
// Select this as best utility if first found
if (i === 0) {
bestUtilityVector = utilityVector;
}
// Update alpha
if (utilityVector[state.currentPlayer] > alpha[state.currentPlayer]) {
alpha[state.currentPlayer] = utilities[state.currentPlayer];
bestUtilities = utilityVector;
}
// Alpha prune
var sum = 0;
for (var j = 0; j < alphaVector.length; ++j) {
sum += alpha[j];
}
if (sum >= 0) {
break;
}
}
}
References:
An implementation of Hypermax without Transposition Tables: https://meatfighter.com/spotai/#references_2
Minimax (negamax variant) with alpha-beta pruning and transposition tables: https://en.wikipedia.org/wiki/Negamax#Negamax_with_alpha_beta_pruning_and_transposition_tables
Original derivation and Proofs of Hypermax: http://uu.diva-portal.org/smash/get/diva2:761634/FULLTEXT01.pdf
The question is quite broad, so this is a similarly broad answer - if there is something specific, please clarify what you don't understand.
Transposition tables are not guaranteed to be correct in multi-player games, but if you implement them carefully they can be. This is discussed briefly in this thesis:
Multi-Player Games, Algorithms and Approaches
To summarize, there are three things to note about transposition
tables in multi-player game trees. First, they require that we be
consistent with our node-ordering. Second, they can be less
effective than in two-player games, due to the fact that it takes more
moves for a transposition to occur. Finally, speculative pruning can
benefit from transposition tables, as they can offset the cost of
re-searching portions of the game tree.
Beyond ordering issues, you may need to store things like the depth of search underneath a branch, the next player to play, and the bounds used for pruning the subtree. If, for instance, you have different bounds for pruning a tree in your first search, you may not produce correct results in the second search.
HyperMax is only a slight variant of Max^n with speculative pruning, so you might want to look at that context to see if you can implement things in Max^n.

Proper code for storing previous values (and refreshing them)

So here's an example of someone (me) writing very bad C# code.
I'm trying to figure out the best method of storing values and replacing them with values as they become known.
Here's how I had been doing it earlier:
int
EMA_Value_Prev4,
EMA_Value_Prev3,
EMA_Value_Prev2,
EMA_Value_Prev,
EMA_Value;
EMA_Value_Prev4 = EMA_Value_Prev3;
EMA_Value_Prev3 = EMA_Value_Prev2;
EMA_Value_Prev2 = EMA_Value_Prev;
EMA_Value_Prev = EMA_Value;
EMA_Value = 0;
// In the below space, some code figures out what EMA_Value is
/* Some amazing code */
// EMA_Value now equals 245 (hypothetically).
Since then, I've used arrays to store this with for loops, like this:
int [] EMA_Value = new int [5];
for (xCount=4; xCount>1; xCount--)
{EMA_Value[xCount] = EMA_Value[xCount - 1]; }
For the way more advanced and experienced (and smarter) coder than I, what I should be doing instead that's either more efficient/elegant/process friendly?
Thanks in advance for any time or attention you give this question. :)
If the reason you're doing it that way is because you want to get the previous values in some case. You can think about using something like a Stack. .NET has a built in stack
Stack<int> stack = new Stack<int>();
stack.push(10)
int topValue = stack.pop()
Every time you get a new value, you call stack.push(newValue). If you want that the previous value, (behaving in the same way as the back button on a browser), you then use pop.
If you're using last N values for something like a runge-kutta ODE solver, than your solution with an array is as good as any other implementation

No double picks in image Array Processing 3.0

i've been trying to make a program that takes (for example) 3 cards at random.
But i don't want my program to grab the same card twice, so that means it can't have duplicates, but i don't know how to do this with a image Array.
String[] card = {
"Aclubs.png",
"2clubs.png",
"3clubs.png",
};
PImage[] cards = new PImage [card.length];
void setup() {
size(1000,1000);
randomCards();
drawCards();
}
int randomCards() {
int i = (round(random(0,2)));
cards[i] = loadImage(card[i]);
return i;
}
void drawCards() {
for (int g = 0; g < 12000; g = g+round((displayWidth * 0.9))/12) {
image(cards[randomCards()], 25+g, 50);
}
}
Instead of using an array, use an ArrayList. Then remove the cards you use. Here's a small example:
ArrayList<String> things = new ArrayList<String>();
things.add("cat");
things.add("dog");
things.add("lizard");
while (!things.isEmpty()) {
int index = int(random(things.size()));
String thing = things.remove(index);
println(thing);
}
Of course, this isn't the only way to do it. You could use a Java Set, or you could use a data structure that holds what you've already picked, or you could store all of the options in a data structure, then shuffle it, then just chose from an index that you increment. Or you could use one of the array functions in the reference to do it.
It's hard to answer general "how do I do this" type questions. Stack Overflow is designed for more specific "I tried X, expected Y, but got Z instead" type questions. So you really should get into the habit of trying things out first. Ask yourself how you would do this in real life, then look at the reference to see if there are any classes or functions that would help with that. Break your problem down into smaller pieces. Write down how you would do this in real life, in English. Pretend you're handing those instructions to a friend. Could they follow your instructions to accomplish the goal? When you have those instructions written out, that's an algorithm that you can start thinking about implementing in code. Staring at code you've already written won't get you very far. Then when you do get stuck, you can ask a more specific question, and it'll be a lot easier to help you.

use five point stencil to evaluate function with vector inputs and converge to maximum output value

I am familiar with iterative methods on paper, but MATLAB coding is relatively new to me and I cannot seem to find a way to code this.
In code language...
This is essentially what I have:
A = { [1;1] [2;1] [3;1] ... [33;1]
[1;2] [2;2] [3;2] ... [33;2]
... ... ... ... ....
[1;29] [2;29] [3;29] ... [33;29] }
... a 29x33 cell array of 2x1 column vectors, which I got from:
[X,Y] = meshgrid([1:33],[1:29])
A = squeeze(num2cell(permute(cat(3,X,Y),[3,1,2]),1))
[ Thanks to members of stackOverflow who helped me do this ]
I have a function that calls each of these column vectors and returns a single value. I want to institute a 2-D 5-point stencil method that evaluates a column vector and its 4 neighbors and finds the maximum value attained through the function out of those 5 column vectors.
i.e. if I was starting from the middle, the points evaluated would be :
1.
A{15,17}(1)
A{15,17}(2)
2.
A{14,17}(1)
A{14,17}(2)
3.
A{15,16}(1)
A{15,16}(2)
4.
A{16,17}(1)
A{16,17}(2)
5.
A{15,18}(1)
A{15,18}(2)
Out of these 5 points, the method would choose the one with the largest returned value from the function, move to that point, and rerun the method. This would continue on until a global maximum is reached. It's basically an iterative optimization method (albeit a primitive one). Note: I don't have access to the optimization toolbox.
Thanks a lot guys.
EDIT: sorry I didn't read the iterative part of your Q properly. Maybe someone else wants to use this as a template for a real answer, I'm too busy to do so now.
One solution using for loops (there might be a more elegant one):
overallmax=0;
for v=2:size(A,1)-1
for w=2:size(A,2)-1
% temp is the horizontal part of the "plus" stencil
temp=A((v-1):(v+1),w);
tmpmax=max(cat(1,temp{:}));
temp2=A(v,(w-1):(w+1));
% temp2 is the vertical part of the "plus" stencil
tmpmax2=max(cat(1,temp2{:}));
mxmx=max(tmpmax,tmpmax2);
if mxmx>overallmax
overallmax=mxmx;
end
end
end
But if you're just looking for max value, this is equivalent to:
maxoverall=max(cat(1,A{:}));

Resources