Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by ashkatchen · Jan 09 at 07:06 PM · tilecheckorderwordsneighbour

Scrabble In Tetris Help Needed

Hey guys. I'm trying to make a game where Scrabble tiles fall down like Tetris tiles and when you make a word, it disappears like Tetris. I managed to make it with single letters but i cant figure out how to connect the letters together.

  void RegisterTile()
     {
         gameLogic.grid[Mathf.FloorToInt(gameObject.transform.position.x), Mathf.FloorToInt(gameObject.transform.position.y)] = gameObject.transform;
         TryWord();
     }
 
     bool CheckValid()
     {
         if(gameObject.transform.position.x > GameLogic.width ||
             gameObject.transform.position.x < 0 || 
             gameObject.transform.position.y < 0)
         {
             return false;
         }
 
         if (gameObject.transform.position.y < GameLogic.heigth && gameLogic.grid[Mathf.FloorToInt(gameObject.transform.position.x), Mathf.FloorToInt(gameObject.transform.position.y)] != null)
         {
             return false;
         }
 
         return true;
     }
     // Update is called once per frame
     void Update()
     {
 
         if(CheckValid())
         {
             check = true;
         }
 
         if (!fingerDown && Input.GetMouseButtonDown(0))
         {
             startPos = Input.mousePosition;
             fingerDown = true;
         }
 
         if (movable)
         {
             timer += 1 * Time.deltaTime;
 
             if (Input.GetKey(KeyCode.DownArrow) && timer > GameLogicNew.quickDropTime || fingerDown && timer > GameLogic.quickDropTime && Input.mousePosition.y < startPos.y - pixelDistToDetect)
             {
                 gameObject.transform.position -= new Vector3(0, 2, 0);
                 timer = 0;
 
                 if (!CheckValid())
                 {
                     movable = false;
                     gameObject.transform.position += new Vector3(0, 2, 0);
                     RegisterTile();
                     gameLogic.SpawnTile();
                 }
             }
             else if (timer > GameLogicNew.dropTime)
             {
                 gameObject.transform.position -= new Vector3(0, 2, 0);
                 timer = 0;
 
                 if (!CheckValid())
                 {
                     movable = false;
                     gameObject.transform.position += new Vector3(0, 2, 0);
                     RegisterTile();
                     gameLogic.SpawnTile();
                 }
             }
 
             if (Input.GetKeyDown(KeyCode.LeftArrow))
             {
                 gameObject.transform.position -= new Vector3(2, 0, 0);
 
                 if (!CheckValid())
                 {
                     gameObject.transform.position += new Vector3(2, 0, 0);
                 }
             }
             else if (Input.GetKeyDown(KeyCode.RightArrow))
             {
                 gameObject.transform.position += new Vector3(2, 0, 0);
 
                 if (!CheckValid())
                 {
                     gameObject.transform.position -= new Vector3(2, 0, 0);
                 }
             }
 
             if (fingerDown)
             {
                 if (Input.mousePosition.x >= startPos.x + pixelDistToDetect) 
                 {
                     gameObject.transform.position += new Vector3(2, 0, 0);
                     startPos = Input.mousePosition;
                     if (!CheckValid())
                     {
                         gameObject.transform.position -= new Vector3(2, 0, 0);
                     }
                 }
                 if (Input.mousePosition.x <= startPos.x - pixelDistToDetect)
                 {
                     gameObject.transform.position -= new Vector3(2, 0, 0);
                     startPos = Input.mousePosition;
                     if (!CheckValid())
                     {
                         gameObject.transform.position += new Vector3(2, 0, 0);
                     }
                 }
             }
         }
         if (fingerDown && Input.GetMouseButtonUp(0))
         {
             fingerDown = false;
         }
     }
 
     public void TryWord()
     {

             WordManager.currentWord += letterName.GetComponent<TMP_Text>().text;
             Debug.Log(letterName.GetComponent<TMP_Text>().text);
     }

it looks like this right now. When a letter hits the bottom, i can see it in the console but when multiple ones hit, i see them all together no matter where they are. I cant find a way to seperate them or show them in order (From left to right / from up to down). I couldnt find any tutorials on how to make a Scrabble game so i ask for your help. Thank you in advance.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by rh_galaxy · Jan 09 at 07:37 PM

I'd go about it this way:

Every time a block hits the bottom and sticks (the grid has changed), check for words on every block in the grid, Right and Down as far as it goes. But you need to have your wordlist indexed so that it does not become too expensive to check for words... GetComponent can certainly not be used as much.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ashkatchen · Jan 09 at 10:06 PM 0
Share

Thats the problem mate. I dont know how to. I tried a few methods but they didnt worked. So i need the help. I cant make a tile recognize it's neighbour tiles. So it takes all of them.

avatar image
0

Answer by Eno-Khaon · Jan 10 at 04:05 AM

Well, if it's based around Scrabble squares and Tetris-style blocks falling into place, then once a tile has settled in place, the new state of your playfield should be a fixed/known state.

Right now, your block positioning appears to be based purely on physical positions in Unity. You should probably move away from that approach and use a pre-specified grid for placement, then reflect those positions back to your placement scheme instead.

With this in mind, you would have a fixed size for your playfield at any given time. Let's say it's 8x8 (to keep this example a bit smaller):

 --------
 --------
 --------
 --M--A--
 --I--D-X
 B-G--R-W
 FDG-OECM
 ZLE-TERQ

In this situation, you can easily store the current state of all the existing blocks in a 2-dimensional array, either as a char array or (preferably) a "Tile" array.

Each tile should contain information about the char associated with it, where that data is copied to the Text component. It's much faster than reading strings from Text components themselves, and the playfield should be storing "Tile" information at all times.

Going back to my example above, the bottom row contains LE TER, where no complete word has been formed yet, but adding the letter 'T' in the middle would complete a new word.

Your playfield can simultaneously keep track of tiles that have changed. After all, the playfield wouldn't be constantly shifting and changing; if a change is manually made, then you can limit your completed-word search to only use letters adjacent to ones that have been updated.

This means two things:

First: When a new letter is placed, check all tiles in its row and column (and diagonally, if applicable) for new words formed. If it's feasible to do so without strings, it would almost definitely be the "faster" solution, but a string still works well enough once you're limiting your search area.

 // Example definition of playfield
 Tile[,] playfield = new Tile[playfieldWidth, playfieldHeight];
 
 // These are the array coordinates where the new Tile landed
 int placedTileX;
 int placedTileY;
 
 // Markers to check word bounds
 int firstCharX = placedTileX;
 int lastCharX = placedTileX;
 int firstCharY = placedTileY;
 int lastCharY = placedTileY;
 
 string wordCheckX = string.Empty;
 string wordCheckY = string.Empty;
     
 // Check backwards for the first letter in the word
 for(int x = placedTileX - 1; x >= 0; x--)
 {
     if(playfield[x, placedTileY] == null)
     {
         break;
     }
     else
     {
         firstCharX = x;
     }
 }
 
 // Check forwards for the last letter in the word
 for(int x = placedTileX + 1; x < playfieldWidth; x++)
 {
     if(playfield[x, placedTileY] == null)
     {
         break;
     }
     else
     {
         lastCharX = x;
     }
 }
 
 // Repeat the same basic principle for Y-axis
 
 // ...
 
 // Add char to your string to compare with dictionary
 for(int x = firstCharX; x <= lastCharX; x++)
 {
     wordCheckX += playfield[x, placedTileY].letter;
 }
 
 // Again, repeat for Y-axis
 
 // Compare with dictionary (or ignore if below minimum letter count)
 
 // After processing is complete...
 for(int y = playfieldHeight - 1; y >= 0; y--)
 {
     for(int x = playfieldWidth - 1; x >= 0; x--)
     {
         playfield[x, y].modified = false;
     }
 }

Second: If you form a word, then by Tetris rules, the involved Tiles will disappear. All tiles above the formed word are moved down to the nearest available height. Then, this is why I mention marking all modified tiles... You'll need to perform the same check as above for the entire range of tiles modified (not one-by-one, but as a group) to check every new row and column they are now adjacent to. On that note, it means my example would need to be changed to accommodate min/max X and Y axis ranges needing to be searched. That makes things a bit more involved, so it's probably better to start simpler, then add more complex logic for searching for all words contained in arbitrary spaces simultaneously.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ashkatchen · Jan 10 at 04:51 PM 0
Share

This is my code for the grid of the playing field:

     public static float dropTime = 0.9f;
     public static float quickDropTime = 0.05f;
     public static int width = 11, heigth = 17;
 
     public GameObject tile;
     public Transform tileSpawn;
 
     public Transform[,] grid = new Transform[width, heigth];
     // Start is called before the first frame update
     void Start()
     {
         SpawnTile();
     }
 
     // Update is called once per frame
     void Update()
     {
 
     }
 
     public void SpawnTile()
     {
         Instantiate(tile, tileSpawn.position, Quaternion.identity);
     }

it's just like you said. I use the tiles as single Tetris blocks and destroy them (at least trying to) when they form a word.

alt text

When i drop a letter, i'm trying to make it recognize the neighbour letters. I'll try your method

resim-2022-01-10-195000.png (9.0 kB)
avatar image Eno-Khaon ashkatchen · Jan 10 at 06:57 PM 0
Share

Probably one of the better changes to make would involve changing your "grid" from Transform data into a "Tile" class attached to each falling block. Because a GameObject will *always* have Transform data associated with it, MonoBehaviour scripts can always easily reference both of those. So your best bet for performance is to put your most relevant data into your grid array (i.e. a class that knows the letter on its tile).

avatar image ashkatchen Eno-Khaon · Jan 10 at 07:02 PM 0
Share

I'm trying to make it work first. :D Before worrying about the performance. But scratch that. Can you teach me how to do that? Or turn me to the right direction to learn it? That would be awesome.

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

134 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How would I find neighbours of a tile in a grid ? 1 Answer

How to check execution order from script? 0 Answers

Locking levels on a level map? 1 Answer

check if each element in string is true simultaneously? 1 Answer

Do Objects Collide? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges