Wheel Matching Game

So I’ve come across a problem, I’m not sure how to approach this either. How would I be able to keep track of what matches with what? Like what position of the wheel is at currently 6438344--720452--spinnnwheelarrows.png

The arrows are just thrown in with paint, but in order to “Win” You must have all these matched.

So all in all, I just dont know how to be able to know what the the wheel is currently matched with. Should I use a array and just move it when the wheel is spun by 45degrees (which moves the wheel by one slot each time)?

I would probably have little collider boxes between the four wheels where the wheels “meet”. Then, each wall of the wheel would have a little collider stick that when it enters or exits a “meet” collider would register it is on that side or not. Then check if it’s a match. Then if it is, it can do another check to determine if all 4 match and you win.

First i would create an array with eight elements. One for each segment of the wheel. Here you can store the type of the segment that should later match with another wheels segment.

Then you have to find out the rotation of the wheel. For example make it so that it rotates around the z-axis.

You can then calculate the angle for each of the eight positions.
6438710--720551--img (2).png
So like in this example at rotation 0° P1 is on top. At rotation 45° P2 is on top etc.
Now you know which element is on top based on the rotation of your wheel. To find the element on the right just pick the element with index i+2 in your array. The one on the down side with i + 4.

I hope this helps :slight_smile:

Start with what you know. Let’s take your sigma panel as an example.
The two cookies align with the angle of 0. As Kashyk said, every counter-clockwise subsequent symbol aligns with an angle at an increment of 45 degrees.

I can’t tell what’s what in your picture, but let’s say that at this point you know the following order is true for the sigma panel (top left):

  • Two cookies
  • Broccoli
  • Peas
  • Broccoli
  • Apple
  • Something
  • Pie
  • Carrots

Now your phi panel (top right) looks like this:

  • Two cookies
  • Pie
  • Umm corn?
  • Potatoes
  • Broccoli
  • Carrots
  • Grey Blob
  • Something

At this point you can tell that the elements Sigma.1 and Phi.5 should match.
If you check them out, it’s Two cookies vs Broccoli, so the symbols don’t match.

If you rotate the sigma panel counter-clockwise, the Carrots should wrap around to the top of the list
i.e.

  • Carrots
  • Two cookies
  • Broccoli
  • Peas
  • Broccoli
  • Apple
  • Something
  • Pie

If you rotate the sigma panel clockwise, the Two cookies should wrap around to the bottom instead
i.e.

  • Broccoli
  • Peas
  • Broccoli
  • Apple
  • Something
  • Pie
  • Carrots
  • Two cookies

To make this behavior in code, first you need to populate your lists with some values that represent these vegetables. Here I will declare an enum to make this readable, but don’t feel obliged to this design in particular. There are infinite ways to make this exactly, but the core principle should be the same.

using System.Collections.Generic;

public class MyPanelSymbols {

  public enum Symbol {
    Cookies,
    Broccoli,
    Apple,
    Peas,
    Pie,
    Carrots,
    Something
  }

  List<Symbol> _list;

  public int Count => _list.Count;
  public Symbol this[int index] => _list[index % Count];

  public MyPanelSymbols(int expectedCountOfSymbols) {
    _list = new List<Symbol>(expectedCountOfSymbols);
  }

  public void AddSymbol(Symbol symbol) {
    _list.Add(symbol);
  }

  public void RotateCW() {
    var item = _list[0];
    _list.RemoveAt(0);
    _list.Add(item);
  }

  public void RotateCCW() {
    var item = _list[Count - 1];
    _list.RemoveAt(Count - 1);
    _list.Insert(0, item);
  }

}

Now you can do some cool things with this someplace else

var sigma = new MyPanelSymbols(8); // this value is only the expected size
sigma.AddSymbol(MyPanelSymbols.Symbol.Cookies);
sigma.AddSymbol(MyPanelSymbols.Symbol.Broccoli);
sigma.AddSymbol(MyPanelSymbols.Symbol.Peas);
sigma.AddSymbol(MyPanelSymbols.Symbol.Broccoli);
sigma.AddSymbol(MyPanelSymbols.Symbol.Apple);
sigma.AddSymbol(MyPanelSymbols.Symbol.Something);
sigma.AddSymbol(MyPanelSymbols.Symbol.Pie);
sigma.AddSymbol(MyPanelSymbols.Symbol.Carrots);

Debug.Log(sigma.Count); // 8
Debug.Log(sigma[0]); // Cookies
Debug.Log(sigma[4]); // Apple
Debug.Log(sigma[10]); // Peas (we've made this wrap around, maybe it's helpful)

sigma.RotateCCW();
Debug.Log(sigma[0]); // Carrots

And similarly you can now test if

if(sigma[0] == phi[4]) {
  Debug.Log("symbols match between the two top panels");
}

Now you only need to keep the visual side of things updated to match what is stored in the model. To do this, every time your rotate a panel by 1 slot, you rotate the matching graphics by the corresponding amount in degrees (45).

That said, there are numerous ways to accomplish the same thing. For example, you don’t have to tumble the values around in order to rotate the list. You can instead move an imaginary list cursor. This will work much faster, because once its initialized, the list itself can be left alone (unless you intend to change the symbols on the fly, which we’ll also add).

Let the list be

  • Two cookies <<<
  • Broccoli
  • Peas
  • Broccoli
  • Apple
  • Something
  • Pie
  • Carrots

Notice the arrow. It points to an element that is the rightmost symbol on the panel.
Imagine if we had a value that keeps the position of this arrow. In this case it’s 0.

If you then rotate the list counter-clockwise, we know the Carrots should come out on top, but instead of modifying the list itself, we only move the arrow.

  • Two cookies
  • Broccoli
  • Peas
  • Broccoli
  • Apple
  • Something
  • Pie
  • Carrots <<<

Only the arrow will wrap around, while everything else is left intact.
The next time you do it, it’ll turn to this, much more efficient then removing/inserting

  • Two cookies
  • Broccoli
  • Peas
  • Broccoli
  • Apple
  • Something
  • Pie <<<
  • Carrots

Now Pie is the rightmost symbol.
Let’s try this in code

public class MyPanelSymbols {

  public enum Symbol {
    Cookies,
    Broccoli,
    Apple,
    Peas,
    Pie,
    Carrots,
    Something
  }

  List<Symbol> _list;
  int _cursor;

  public int Count => _list.Count;
  public Symbol this[int index] => _list[(_cursor + index) % Count];

  public MyPanelSymbols(int expectedCountOfSymbols) {
    _list = new List<Symbol>(expectedCountOfSymbols);
    _cursor = 0;
  }

  public void AddSymbol(Symbol symbol) {
    _list.Add(symbol);
  }

  public void ChangeSymbol(int index, Symbol symbol) {
    _list[(_cursor + index) % Count] = symbol;
  }

  public void RotateCW() {
    _cursor--;
    if(_cursor < 0) _cursor = Count - 1;
  }

  public void RotateCCW() {
    _cursor++;
    if(_cursor > Count - 1) _cursor = 0;
  }

}

After we normally load all the symbols

Debug.Log(sigma.Count); // 8
Debug.Log(sigma[0]); // Cookies
Debug.Log(sigma[4]); // Apple
Debug.Log(sigma[10]); // Peas

sigma.RotateCCW();
Debug.Log(sigma[0]); // Carrots

sigma.ChangeSymbol(0, MyPanelSymbols.Symbol.Pie);
Debug.Log(sigma[0]); // Pie

Why this works?
Well because we made our index wrap around previously, we can now play with the fact.
You can supply any positive index whatsoever and it’ll always evaluate in the range from 0 to Count - 1
For this we use the division remainder operator (%)

When used with integers it’ll always return the remainder of the division operation.
For example 8 % 3 = 2 because you can fit 3 two times in 8, and what is left is 2.
This means that the result will never surpass the right operand (in this case 3), and you can reliably use this to compute a modulo.

We don’t support supplying negative indices here, however.

But look, our cursor is also confined to these rules. I could’ve used % as well in RotateCW and RotateCCW but didn’t to make it more readable. Because we always change cursor by 1, the outcome is easy to predict, and if it becomes -1, this means it should become 7 instead, and the other way around, if it becomes 8 it should become 0 instead.

When you add this “magic” number to your queried index, the resulting index is both confined within the range of the list AND offset by this magic internal number.

When we do RotateCCW and query sigma for index 5, the internal index evaluation is
(7+5) % 8
= 12 % 8
= 4

so Apple

And sure, if you look at your top left panel, and count slots from 0 (Cookies), to 5, counter-clockwise, this is the slot where you expect the Apple to be after you rotate the entire panel counter-clockwise.

You can also scale this to any desired amount of symbols (try it), however you’ll get IndexOutOfRange errors if you attempt to use a panel without symbols, or if you pass in negative indices.