MemoryCardGame
Tags: rails, javascript
Published: 2021-05-18 01:04:30



"In some ways, programming is like painting. You start with a blank canvas and certain basic raw materials. You use a combination of science, art, and craft to determine what to do with them." - Andrew Hunt

##Step1: Deciding type of website
This is first project using javaScript so I didn't want to do complex project instead I decided to make simple memoryCardGame.

##Step2: Setting backend
###table relation
```
class Category < ApplicationRecord
    has_many :cards
end

class Card < ApplicationRecord
  belongs_to :category
end
```
###Controller
Use scaffold
rails g scaffold Category name
rails g scaffold Card name url category:belongs_to
```
class CategoriesController < ApplicationController
  before_action :set_category, only: [:show, :update, :destroy]

  # GET /categories
  def index
    @categories = Category.all

    render json: @categories, only: [:id, :name], include: {
      cards: {
        only: [:id, :name, :url, :category_id] 
      }
    }
  end

  # GET /categories/1
  def show
    render json: @category, only: [:id, :name], include: {
      cards: {
        only: [:id, :name, :url] 
      }
    }
  end

  # POST /categories
  def create
    @category = Category.new(category_params)

    if @category.save
      render json: {
        status: 201,
        store: @category
      }, status: :created, location: category_path(@category)
    else
      render json: {
        status: 422,
        errors: @store.errors.full_messages.join(", ")
      }, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /categories/1
  def update
    if @category.update(category_params)
      render json: @category
    else
      render json: @category.errors, status: :unprocessable_entity
    end
  end

  # DELETE /categories/1
  def destroy
    @category.destroy
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_category
      @category = Category.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def category_params
      params.require(:category).permit(:name)
    end
end
```
##Step3: Setting frontend
###index.html
####Create form
fetch post request to add new category with new 6 cards
####Category-container
fetch get request to show a list of category
####Game
When user clicks the play button next to the each list then event function will generate new Game with that category.
###styles.css
Since I have show the card flips to user. I put two different images (font-face and back-face) in the same location and made them 3d.
https://www.w3schools.com/cssref/css3_pr_transform.asp
https://www.w3schools.com/cssref/css3_pr_transform-style.asp
https://www.w3schools.com/cssref/css3_pr_transition.asp
```
#memory-game {
    width: 640px;
    height: 640px;
    margin-right: 5%;
    border-radius: 5px;
    display: flex;
    flex-wrap: wrap;
}

.memory-card {
    /*board is 640 we have 160 for each but we need somespace with each other so -10 and have margin 5px*/
    width: calc(25% - 10px);
    height: calc(33.333% - 10px);
    margin: 5px;
    position: relative;   
    transform: scale(1);
    /*preserve-3d: Specifies that child elements(.front-face and .back-face) will preserve its 3D position*/
    transform-style: preserve-3d;
    transition: transform .5s;
}

.memory-card.flip {
    transform: rotateY(180deg);
}

/*put front and back same spot*/
.front-face, .back-face {
    width: 100%;
    height: 100%;
    position: absolute;
    border-style: solid;
    border-color: wheat;
    border-width: 2px;
    border-radius: 5px;
    backface-visibility: hidden;
}

/*then rotate front 180deg to only see the back-face at first*/
.front-face {
    transform: rotateY(180deg);
}
```
###src/index.js
This part is relatively easy then setting up the board. As long as I follow the logic everything is okay.
Useful-1: style.order
https://www.w3schools.com/jsref/prop_style_order.asp
The order property specifies the order of a flexible item relative to the rest of the flexible items inside the same container.
```
function shuffle(){
    const cards = document.querySelectorAll('.memory-card');
    for(let i=0; i<cards.length; i++){
        let randomPos = Math.floor(Math.random() * 12);
        cards[i].style.order = randomPos
    }
}
```
Useful-2: classList
https://www.w3schools.com/jsref/prop_element_classlist.asp
classList.add(); Adds one or more class names to an element.

##Future 
For now it only works 6 set of cards. I want to modify this project so that it can generate game with any sets of cards.