Boardgame-Map with crossroads etc - delphi

I have a little logical problem over here.
As the title says, I try to build a boardgame as a computer-program (maybe with internet-support, but thats another story)
As for now, I have a map, which has some crossroads in it, hence I cannot simply define the fields as '1, 2, 3, 4, ...' because if there is a crossroad at field 10, I would have more than one field which has to be labeled 11 (Because then there is a field left and right of field 10, for example.)
So the problem is, if I cannot define the Board in numbers then I cannot simply get the possible positions a player can take when he rolls 2d6-dices with calculating 'Field-Nr. + RandomRange(1,6) + RandomRange(1,6)'
Does anybody have an idea, how to define a Map like this on another way, where I still can calculate the possible new-fields for Player X with a 2d6-dice-roll?
Thanks in advance.

If i understand well... (i don't thing so) this might help you. Just use dynamic arrays for your boardgame field and change your actions after the dimensions x,y .... Look at this "type Name = array of {array of ...} Base type; // Dynamic array"

It sounds like you have a graph of connected vertices. When a player is at a particular vertex of N edges, assuming N < 12, the new Field will be reached from traversing edge number N % ( rand(6) + rand(6) ).
You could also just do rand(12), but that would have an even distribution, unlike 2d6.

Instead of dynamic arrays, I would recommend using a linked-list of records to describe the surrounding cells, and traverse the player's location and possible moves using that linked-list.
First, define a record that describes each cell in your board's playable grid (the cells on the grid can be four-sided like a chessboard, or hexagonal like in Civilization V) ... each cell record should contain info such as coordinates, which players are also in that cell, any rewards/hazards/etc that would affect gameplay, etc. (you get the idea).
Finally, the linked-list joins all of these cells, effectively pointing to any connected cells. That way, all you'd need is the cell location of Player X and calculate possible moves over n amount of cells (determined by the dice roll), traversing the adjoining cells (that don't have hazards, for example).
If all you want is to track the possible roads, you can also use this approach to identify possible paths (instead of cells) Player X can travel on.

Related

Tableau: How to display size as the number of records for the same lat,long

On the same (lat,long) on a Tableau-Desktop map, I want the size of a dot to be proportional to the number of records at that location. I tried count/sum(Number of Records) built-in tableau measure, I created a SeqId and tried count(SeqId) for Size, neither worked. Here is a sample of my data, as you can see:
(44.92810490,-74.89186500) has one Record
(44.69948730,-73.45291240) has five Records
(44.72143010,-73.72375280) has 10 records
I would like the point to be proportional to the number of records at that location. Help is Much appreciated
Musa
Seq Id,Census,Gender,Lat,Long
1,1860,F,44.92810490,-74.89186500
2,1870,M,44.69948730,-73.45291240
3,1870,F,44.69948730,-73.45291240
4,1870,M,44.69948730,-73.45291240
5,1870,F,44.69948730,-73.45291240
6,1870,F,44.69948730,-73.45291240
7,1870,M,44.72143010,-73.72375280
8,1870,M,44.72143010,-73.72375280
9,1870,M,44.72143010,-73.72375280
10,1870,M,44.72143010,-73.72375280
11,1870,M,44.72143010,-73.72375280
12,1870,M,44.72143010,-73.72375280
13,1870,M,44.72143010,-73.72375280
14,1870,M,44.72143010,-73.72375280
15,1870,M,44.72143010,-73.72375280
16,1870,M,44.72143010,-73.72375280
Can you try this?
Create a calculated field "Geo" with this definition
IFNULL(STR([Lat]),"")+ ","+IFNULL(STR([Long],"")
Move this field in "size" mark using Count([Geo])
Hope this should give you the desired result.
Put Latitude on the Rows shelf, and then right click on the pill and convert it to a dimension. Make sure it stays continuous.
Likewise, put Longitude on the Columns shelf and convert it to a dimension
Put SUM(Number of Records) on the size shelf
Important, Don't have any other dimensions on any shelves, leave SeqId off
This approach will make one mark for each unique latitude/longitude pair and size that mark according to how many times that pair appears in the data set.
A problem you will probably notice is that two latitudes that differ only in the final decimal place are treated as distinct latitudes. That may not make the most useful visualization. You can bin nearby latitudes together by making a calculated field to round values to the degree you wish. If you do that, be sure to make your field a continuous dimension, and also set its geographic role. It has the effect of snapping lat/long pairs to a grid. As an alternative to rounding, you can look into the hexbinx() and hexbiny() functions.
For a heat map based on square or hex grids, you may want to try using (partially transparent) colors instead of size to indicate density.

spatial set operations in Apache Spark

Has anyone been able to do spatial operations with #ApacheSpark? e.g. intersection of two sets that contain line segments?
I would like to intersect two sets of lines.
Here is a 1-dimensional example:
The two sets are:
A = {(1,4), (5,9), (10,17),(18,20)}
B = {(2,5), (6,9), (10,15),(16,20)}
The result intersection would be:
intersection(A,B) = {(1,1), (2,4), (5,5), (6,9), (10,15), (16,17), (18,20)}
A few more details:
- sets have ~3 million items
- the lines in a set cover the entire range
Thanks.
One approach to parallelize this would be to create a grid of some size, and group line segments by the grids they belong to.
So for a grid with sizes n, you could flatMap pairs of coordinates (segments of line segments), to create (gridId, ( (x,y), (x,y) )) key-value pairs.
The segment (1,3), (5,9) would be mapped to ( (1,1), ((1,3),(5,9) ) for a grid size 10 - that line segment only exists in grid "slot" 1,1 (the grid from 0-10,0-10). If you chose a smaller grid size, the line segment would be flatmapped to multiple key-value pairs, one for each grid-slot it belongs to.
Having done that, you can groupByKey, and for each group, calculation intersections as normal.
It wouldn't exactly be the most efficient way of doing things, especially if you've got long line segments spanning multiple grid "slots", but it's a simple way of splitting the problem into subproblems that'll fit in memory.
You could solve this with a full cartesian join of the two RDDs, but this would become incredibly slow at large scale. If your problem is smallish, sure, this is an easy and cheap approach. Just emit the overlap, if any, between every pair in the join.
To do better, I imagine that you can solve this by sorting the sets by start point, and then walking through both at the same time, matching one's current interval versus another and emitting overlaps. Details left to the reader.
You can almost solve this by first mapping each tuple (x,y) in A to something like ((x,y),'A') or something, and the same for B, and then taking the union and sortBy the x values. Then you can mapPartitions to encounter a stream of labeled segments and implement your algorithm.
This doesn't quite work though since you would miss overlaps between values at the ends of partitions. I can't think of a good simple way to take care of that off the top of my head.

How can I use bwlabel or regionprops to extract set of pixels of each label?

I'm following this tutorial
The goal is to be able to spit out either:
a. the center of each labeled object
b. all pixels associated with each labeled object
in a way that I have an array of either 'a.' for each object, or 'b.' for each object
I'm really not sure how to go about this. Are there matlabl tools to help extract these set of pixels or centers - per - label?
Update
I did manage to circle 80% of what I wanted using reigionprops, however it doesn't capture label precisely, just sets a circle around them while capturing the background as well, is that really unavoidable? I'm just not sure how to access the set of pixel per each circled item.
r=regionprops(L, 'All'); imshow(imagergb); areas={r.Area}; Bboxes={r.BoundingBox};
for k=2:numel(r)
if areas{k}>50 && areas{k} < 1100
rectangle('Position',Bboxes{k}, 'LineWidth',1, 'EdgeColor','b', 'Curvature', [1 1]);
end
end
So what I'm trying to do is for example.
I thought it might just be
r = regionprops(L, 'PixelIdxList')
then
element1 = r(1).PixelIdxList
but couldn't figure out how to get the position of each pixel
I also tried
Z= bwlabel(L);
but imshow(Z==1) spits out all labels and imshow(Z==2) spits out background, all labels and background. couldn't test bwlabeln since I'm not exactly sure what to enter for r and c arguments.
Using regionprops(L, 'PixelIdxList') is correct. It gives you lists of pixel indices for each label. You can then convert them to [x,y] coordinates using (for the first label, for example)
[y,x] = ind2sub(size(L), r(1).PixelIdxList)
You can get label centers by using regionprops(L, 'Centroid'). This already gives you [x,y] coordinates for each label. Note that these are subpixel coordinates, so you may need to round them if you want to use them as indices.

BattleShip Game IOS conceptual design

ok, here´s a first time noob question, sorry if that´s stupid.
I was just wondering, for a battleship kind of game, would it be a waste of memory to build a set of objects for each cell (10X10=100), with position(x,y) and state(empty,hit,missed) properties?
I was wondering if it would be better to only create an object Grid and use methods to calculate the cell positions whenever necessary (when handling cell selection with touches or drawing for example)..
The former is problematic because you may have ships that sit side-by-side or end to end and it will become difficult to know when one is completely destroyed just from the data structures you described. Two hits side-by-side could be two hits on the same ship, two hits to two different ships, or even a sinking for the smallest ship.
Go with the latter for sanity's sake.
If I was doing this, I would keep it simple, Have a 2 dimensional array, that's your 10 by 10 grid.
When someone takes a turn, calculate the position and;
if it's a miss, insert a 0 in that array cell
if it's a hit, insert a 1 in that array cell

SSRS line chart not connecting data points

I've looked high and low and can't seem to find an answer to what appears to be quite a straightforward issues (I would think).
I have a line chart where there is data at several points in a series but only only one set of points link up.
Does anyone know why this is? Is it to do with my data? If it is, I am struggling to see any relationships in the data that may explain this behavior.
Here is what I mean:
As you can see, the red diamonds should be connecting - the same could be said about the blue squares and the dark blue triangles. Any thoughts?
Apologies if my colors are wrong - I'm colorblind.
Okay, so I worked this out.
Firstly, in order to get the lines to join up, you need to set the EmptyPoint colour for the series.
select your series in your chart
In the properties tab (not the dialog) drill down into the EmptyPoint property and set the colour to be Black
This will get them joining up - yay! But part of the line is colour and the other part is black, right? That's a bit silly, especially considering if you leave the colour to Automatic on the EmptyPoint that it will be transparent.
So, then we need to get the series and the EmptyPoint's colours in sync.
Using code from here. I added some code to the code of the report.
1). Right click on an empty space on the report and select "Report Properties"
2). In the code tab, paste the following:
Private colorPalette As String() = {"#418CF0", "#FCB441", "#E0400A", "#05642E", "#1A3B69", "#BFBFBF", "#E0400A", "#FCB441", "DarkBlue", "Tomato", "Orange", "CornflowerBlue", "Gold", "Red", "Green", "LightBlue", "Lime", "Maroon", "LightSteelBlue", "Tan", "Silver"}
Private count As Integer = 0
Private mapping As New System.Collections.Hashtable()
Public Function GetColor(ByVal groupingValue As String) As String
If mapping.ContainsKey(groupingValue) Then
Return mapping(groupingValue)
End If
Dim c As String = colorPalette(count Mod colorPalette.Length)
count = count + 1
mapping.Add(groupingValue, c)
Return c
End Function
Then we need to call this code when setting the colour of the series and of the EmptyPoint.
Select your series
In the properties tab paste something the following (replace WhateverTheGroupIsForYourSeries with your series group name): =Code.GetColor(Fields!*WhateverTheGroupIsForYourSeries*.Value)
Drill down to the color element of the EmptyPoint Series property
Paste the same text as from point two [e.g. =Code.GetColor(Fields!*WhateverTheGroupIsForYourSeries*.Value)]
And voila! You're done!
I can't believe how unnecessarily difficult this is :D
I just had a problem where it was showing markers but not the lines. I ended up solving it by wrapping the expression in a CInt() to convert it to an integer.
Another way to handle this is to do a recursive select (if you have very large data sets don't do this, it kills performance). So you could make your dataset:
SELECT *, ROW_NUMBER() over(partition by Store order by Date desc) as rn
FROM StorePerformance
Now you can have your category group be rn (it should group by rn and sort by rn) but select date for its label. This will still display the date on your x axis, but since you are grouping by rn the data will still be continuous and all of the lines will connect. Also your legend will still match.
I still haven't looked deeply into how much this shifts the data points since we are plotting with row number and displaying date, but if you are mainly concerned with visualizing trends in the lines and aren't as concerned with where they are at a given point in time in relation to one another, it will serve you just fine. Otherwise I would leave the chart the way it is and just read the plot points, which are still valid data.
Solution
Just put your Fields!(YourSeriesGroup).Value in Series Groups to above of
Fields!(YourCategoryGroup).Value in Category Groups, your series group should be in both Series Groups and Category Groups (should be above of your initial category group).
And after that right click horizontal axis and select Horizontal Axis Properties. Set Axis Type to Scalar and click OK.
Result

Resources