LUA 기초문법

# 1) :recycle: 변수와 연산자와 타입
### 1-1) 지역변수 및 전역변수

- 지역변수
```
local [변수명] = [값]

local [변수명1] , [변수명2] = [변수1의 값] , [변수2의값] # 변수는 한꺼번에 여러개를 선언 가능
```
※ 로컬의 범위는 기본적으로 파일로 한정되지만 ***함수*** 내에서 쓰일 경우는 함수 안으로 한정함 

- 전역변수
```
[대문자 변수명] = [값]
```
※ 모든 스크립트에서 접근 가능한 변수


<br>

### 1-2) 연산자
- 계산연산자
    - `+` : 더하기
    - `-` : 빼기
    - `/` : 나눈 값
    - `*` : 곱하기
    - `%` : 나머지 값
- 조건연산자
    - `>` `>=` `==` `<` `<=` 등 여타 언어와 유사
    - 단 , 다르다는 `~=`로 표시  (다른언어의 `!=` 와 혼동주의)
- 논리연산자
    - LUA에서는 `and` `or` `not` 으로 쓴다
    - 타 언어의 `&&` `||` `!` 와 혼동 주의
- 증감연산자
    - 증감연산자는 따로 없다
    - 증감식을 사용하기 위해서는 `[변수1] = [변수1] + [변수2]` 로 명확히 표시


### 1-3) 문자열
```
-- 개행
local str1 = "hello\nnice to meet you"  -- \n로 개행가능

-- 탭
local str2 = "tab1\t tab2\t tab3\t"  -- \t로 들여쓰기 가능

-- 문자열 길이
local str3 = "hello" 
local len = #str3      -- #로 문자열의 길이 취득 가능 [len의 값은 5]


-- 문자열 연결
local str4,str5 = "hello" ,"nice to meet you"
print(str..str5) --  ..로 문자연결
```

### 1-4) nil
- `nil` 이란?
    - 타 언어의 `null` 과 같이 값을 가지지 않는 값
    - `nil` 값이 되는 조건
        - 조건 1 : 선언되지 않은 변수 호출
            ```
            print(v)  
            ```
        - 조건 2 : 선언만 되고 값이 없는 변수 호출
            ```
            local v
            print(v)
    
    
            local v1 , v2 = "variant"
            print(v1 , v2)  -- v1에는 "variant"가 출력되지만, v2에는 nil이 출력
            ```
        - 조건 3 : 직접 값에 nil 부여
            ```
            local v = nil
            print(v)
            ```

### 1-5) 타입 별 비교값
```
-- True로 인식되는 타입 : Number , string (0과 공백문자열도 포함)
-- 변수값에 true를 줄수도 있음

local x,y = 10,"hi"
local a = not x  -- a = not true 
print(a)         -- a = false
local a = not y  -- a = not true 
print(a)         -- a = false
```
```
-- False로 인식되는 타입 : nil
-- 변수값에 false을 줄수도 있음

local i
local j = nil
print(not i , not j) -- not false = true
```

### 1-6) 주석달기
- 한 행만 주석 달기 : `-- 주석 내용`
- 복수행 주석 달기 : `--[[ 주석 내용 ]]--`


# 2) :file_cabinet: 테이블
### 2-1) 테이블이란?
- 이름 때문에 햇갈릴수도 있지만 타 언어의 ***배열***과 같은 ***레퍼런스계 메모리형식***임
- 다만 주소는 ***1*** 부터 시작 (타 언어에선 대개 `0` 부터 시작하니 혼동 주의)

- 형식
```
local table = { "love it" , 5656 , true }  -- 문자열, 숫자 , 불린값 등 여러타입이 한꺼번에 올수 있음

print(table[2])       -- 테이블의 주소입력 (5656이 출력)
print(#table)         -- 테이블의 길이 (3이 출력)
```

### 2-2) keyValue
- JSON형태와 유사한 Key - Value 형태로 만들수 있다
```
local people = {
  {name = "Kim Minsu" , age = 26 , class="admiral" ,country ="korea" },
  {name = "Kato Kiyomasa" , age = 55 , class="vice admiral" ,country ="japan"},
  {name = "Sun Jian" , age = 47 , class="colonel" ,country ="taiwan"}
}

local keyName = "name"
local keyCountry = "country"

print("name : "..people[1].name .. "\nclass : " ..people[1].class)
-- `.key` 방식 ⇒ name : Kim Minsu  class : admiral 이 출력
print("name : "..people[2]["name"] .. "\nage :" ..people[2]["age"]) 
-- `["key"]` 방식 ⇒ name : Kato Kiyomasa   age : 55 가 출력
print("name : "..people[3][keyName] .. "\ncountry : " .. people[3][keyCountry] ) 
-- `["key"]` 방식 ⇒ name : Sun Jian   country : taiwan 이 출력
```

```
-- keyValue와、다른 요소의（Number,String) 혼용
local IE = {"hello" , class="shogun" , 33}  
print(IE[2]) -- 단、keyValue의 값은 주소에서 제외됨 (33이 출력)
print(IE.name)
```

# 3) :scales: 조건문
### 3-1) if 조건문
```
-- 기본 구문 

if [조건] then 
    [실행문]
end
```
```
--  elseif와 else 추가

if [조건] then       -- 첫째조건
    [실행문]
elseif [조건] then   -- 둘째조건
    [실행문]
elseif [조건] then   -- 셋째조건
    [실행문]   
else                -- 위의 조건 어떤것에도 부합하지 않는 조건
    [실행문]
end
```



# 4) :repeat: 반복문
### 4-1) for 반복문

- 기본 문법
```
for var= 1 , 5 , 1 do      -- for [반복변수]=[시작값], [끝 값] , [증가] do
    print(var)             --  [반복할 내용]
end                        -- end
```

- `ipairs` 와 `pairs`
    - `ipairs`는 테이블과 , `pairs`는 KeyValue와 엮인다. 
    -  테이블 및 keyvalue를 리스트 형식으로 출력한다
    ```
    -- ipairs의 예
    local t = {22,33, "park" , -1 ,"kim"}
    for i , e in ipairs(t) do      -- i 는 index e 는 element 
      print(i , e , type(e))
    end
    ```
    ```
    -- pairs의 예
    local table = {11 , x=22 , y=33 , 44}   -- 다른요소 (number , string)가 올수 있긴 하지만 key가 index로 출력
    for k , v in pairs(table) do            -- k는 key v는 value  
      print(k , v)
    end 
    ```
<br>

- `break`
    - 반복문에서 빠져나올수 있는 내장함수다
    ```
    local t = {1,2,3,0,5,6,7,8}
    local sum = 0
    for i , v in inpairs(t) do
        if v = 0 then 
            break   -- t의 v가 0 일시 반복문이 종료됨
        end
        print(i,v)  -- 출력 되는 값은 1 1 , 2 2 , 3 3 만 출력된다.
        sum = sum + v
    end
    print(sum)
    ```

### 4-2) while 반복문
- `while` 구문
    - while [불린값] do 의 형식이다. false가 아닐시 무한 반복된다
    ```
    while true do           
        [반복할 내용]
    end
    ```


### 4-3) repeat ~ until 반복문
- repeat에 반복내용 , until에 조건이 들어감
- 일단 한번은 무조건 실행하고 그 뒤에 조건검사가 이루어짐
```
local i = 1

repeat 
    print (i)
    i = i + 1
until i > 5 
```

# 5) :rotating_light: 함수(function)
### 5-1) 함수란?
- 기능을 담고있는 하나의 객체
- 단 , 호출됨으로써 기능을 행함

### 5-2) 함수 사용례
- 구문
```
local fuction [함수이름](매개변수)   -- 매개변수는 받지 않을수도 있음 (보내는 매개변수가 받는 매개변수보다 많을시 nil값임)
    [수행기능]
    return  [ 리턴 값 ]            -- 리턴값이 없거나 , 리턴이 없는 함수는 리턴 값이 nil임 
end

함수이름(매개변수)      --함수 호출
```
- 기본 함수
```
local function pow2(x)
    local xs = x^2
    return xs
end
print(pow2(6))
```
- 익명함수
```
-- 익명함수란 함수 자체에는 이름이 없는 함수를 뜻함
-- 다만 , 그 이름을 변수로 대체하고 있음 
local call = function(a,b) return print(a+b) end 
call(12,12)
```
- 리턴값이 2개이상인 함수
```
local function divmod(x,y)
  local d = math.floor(x/y)
  local r = x%y
  return d , r   -- 단, 각 리턴값은 콤마로 구분한다.
end
local seeD,seeR = divmod(100,3)
print(seeD,seeR)
```
- 괄호 생략 예
```
-- 매개변수가 하나이며 table또는 문자열일 경우 , 호출할 때 괄호 생략이 가능함
local function call(name)
  print(name)
end
call "Lee"
```
- 매개변수 기본값 설정
```
local function func(a,b)
  a = a or 2  -- 호출할때 매개변수가 따로 없을시 2로 설정함
  b = b or 3  -- 호출할때 매개변수가 따로 없을시 3으로 설정함
  return print(a^b)
end
func()     -- 값 1
func(3)    -- 값 27
func(4,4)  -- 값 256
```
### 5-3) 함수테이블
- 함수 테이블이란? 
    - 함수를 통해 테이블을 제어하는것!
<br>

- 테이블 값 변경
```
local a   = {11,22, x = 3}

local function transTable(t)
  t.y = -10           -- 호출되면 a = { 11 , 22 , x = 3 , y = -10  } 로 "y = -10" 가 추가
end
```

- 가변테이블
```
local function addTable(...) -- 매개변수 ...가 포인트! 
  local b ={...}
  showTable(b)
end
addTable(11,22,33,44,55,66)
```

- 테이블 함수
```
local t = {
  x = 11,
  f = function () print("greeting") end,
}
t.f()   --greeting이 출력된다.
```

- 테이블 함수 콜론문법
```
local t = { x = 11 , 22 , "hello"}

function t.g(self ,a)    -- t.g : t 테이블을 안에 g라는 함수 추가 (self 매개변수는 t 테이블을 의미)  
  local r = a + self.x   -- 즉 r = [매개변수 a] + [self.x(= 11)] 의 상태인것임
  return r
end
local a = t:g(100)       -- 테이블 함수 호출 [ t:g(100) = t.g(t,100) ]

print = a
```
※ 테이블 함수 호출시 콜론문법 `:` 을 쓰게되면 첫번째 매개변수로 자동으로 self를 넘겨줌 
 (자동적으로 매개변수 100은 a에 대입)

- 테이블 함수 콜론문법
```
local t = { x=5, y=6 }
function t:g(b)
  local r = self.x + self.y + b 
  return r
end
local b = t:g(1)
print(b)
```

※ `function t:g(b) end` 는 `function t.g(self,b) end` 로 봐도 무방하다

# 6) :inbox_tray: require
### 6-1) require이란?
- 외부파일을 가져오는 기능을 가짐

### 6-2) 용례
- 첫번째 용례 (기본 문법)
    - requireTest1 파일
        ```
        print("test to require ~^-^")
        ``` 
    - 메인파일

        ```
        print("-------------------")
        require "requireTest1"    -- 외부파일 불러오기 
        print("successed call to requireTest1")
        print("-------------------")
        ```
    - 출력 결과
        ```
        -------------------
        test to require ~^-^
        successed call to requireTest1
        -------------------
        ```

<br>

- 두번째 용례 (함수)
    - requireTest2 파일
        ```
        local function add( a , b )
          local s = a+b
          return s
        end
        
        return add
        ``` 
    - 메인파일
        ```
        print("-------------------")
        local f= require "requireTest2"
        print(f(2,3))
        print("successed call to requireTest2")
        print("-------------------")
        ```
       
    - 출력 결과
        ```
        -------------------
        5
        successed call to requireTest2
        -------------------
        ```

<br>

- 세번째 용례 (테이블 함수)
    - requireTest3 파일
        ```
        local function add( a , b )
          local s = a+b
          return s
        end
        
        local function sub(a,b)
          local s = a-b
          return s
        end
        
        local t = {add = add , sub = sub , pi= 3.14}
        
        return t
        ```
    - 메인파일
        ```
        print("-------------------")
        local t = require "requireTest3"
        print(t.pi)
        print(t.add(2,3))   --print(t[1](2,3))
        print(t.sub(2,3))   --print(t[2](2,3))
        print("successed call to requireTest3")
        print("-------------------")
        ```
    - 출력 결과
        ```
        -------------------
        3.14
        5
        -1
        successed call to requireTest3
        -------------------
        ```

<br>

- 네번째 용례 (다른 디렉토리에서 불러오기)
    - ./requireTest/requireTest4 파일
        ```
        print("test to dir require (0 o 0 ;)")
        ```
    - 메인파일
        ```
        print("-------------------")
        local t2 = require "requireTest.requireTest4"
        print("successed call to requireTest4")
        print("-------------------")
        ```
    - 출력 결과
        ```
        -------------------
        test to dir require (0 o 0 ;)
        successed call to requireTest4
        -------------------
        ```

<br>


# 7) :hammer_pick: 알아두면 좋은 내장함수

### 7-1) io 함수
```
io.read()            -- 입력을 받아들임
io.write("hello")    -- 문자열을 출력함
```

### 7-2) math 함수
```
print(math.abs(-10))                     -- abs : 절대치로 변경
print(math.floor(5.9))                   -- floor : 소수점 이하를 올림
print(math.ceil(5.1))                    -- ceil : 소수점 이하를 내림
print(math.min(1000,1,2000,3000,4000))   -- min : 최고값을 반환함
print(math.max(2,1,3,5,4000))            -- 최소값을 반환함
print(math.random(1,100))                -- a부터 b 까지의 난수를 반환함 (아마 제일 중요할듯)
```

### 7-3) string 함수
```
string.sub("hello", 3, 4)                      -- 인텍스 부분만 출력
string.find("hello", "llo")                    -- 문자열의 인덱스 찾음
string.gsub("hello japan", "japan", "korea")   -- 문자열 대체
string.upper("hello")                          -- 대문자 변환
string.lower("HELLO")                          -- 소문자 변환
```

### 7-4) 그 외 자주쓰이는 함수
```
tonumber("111")    -- 타입을 number로 변환
tostring(123)      -- 타입을 string으로 변환
type("hello")      -- 변수타입 확인

```